Игра «Поросенок Петр» на Delphi 7 без VCL

Тема в разделе "WASM.WIN32", создана пользователем Tech, 10 июн 2026.

  1. Tech

    Tech Member

    Публикаций:
    0
    Регистрация:
    1 апр 2026
    Сообщения:
    47
    Реализация игры «Поросенок Петр» на Delphi 7 без использования VCL, только старые добрые функции WinAPI.

    1673418330160623062.jpg

    Игрок управляет красным трактором, который может перестраиваться по трём полосам,
    уворачиваясь от встречных машин (синих легковых и коричневых грузовиков).

    Код (Pascal):
    1. program Game;
    2.  
    3. uses
    4.   Windows, Messages;
    5.  
    6. const
    7.   ID_TIMER = 1;
    8.  
    9.   ROAD_WIDTH = 360;
    10.  
    11.   SCREEN_WIDTH = 800;
    12.   SCREEN_HEIGHT = 700;
    13.  
    14.   FPS = 60;
    15.  
    16.   TIMER_INTERVAL = 700 div FPS;
    17.  
    18. const
    19.   BLACK       = $000000;
    20.   WHITE       = $FFFFFF;
    21.   GRAY        = $646464;
    22.   DARK_GRAY   = $3C3C3C;
    23.   GREEN       = $1E641E;
    24.   YELLOW      = $64FFFF;
    25.   RED         = $3232DC;
    26.   BLUE        = $FF6432;
    27.   LIGHT_BLUE  = $FF9664;
    28.   BROWN       = $13458B;
    29.  
    30. type
    31.   TCarKind = (ckCar, ckTruck);
    32.  
    33.   TCar = record
    34.     Lane: Integer;
    35.     Y: Integer;
    36.     Kind: TCarKind;
    37.   end;
    38.  
    39.   TRoad = record
    40.     Left: Integer;
    41.     ScrollY: Integer;
    42.   end;
    43.  
    44.   TPlayer = record
    45.     Lane: Integer;
    46.     X: Integer;
    47.     Y: Integer;
    48.     MoveDelay: Integer;
    49.   end;
    50.  
    51.   TCars = record
    52.     List: array of TCar;
    53.     Count: Integer;
    54.   end;
    55.  
    56.   TGameplay = record
    57.     Score: Real;
    58.     HighScore: Real;
    59.     Active: Boolean;
    60.     Speed: Real;
    61.     CarTimer: Integer;
    62.   end;
    63.  
    64.   TGame = record
    65.     Road: TRoad;
    66.     Player: TPlayer;
    67.     Cars: TCars;
    68.     Gameplay: TGameplay;
    69.   end;
    70.  
    71.   TGraphics = record
    72.     BufferDC: HDC;
    73.     hBitmap: HBITMAP;
    74.     hOldBitmap: HBITMAP;
    75.   end;
    76.  
    77. var
    78.   Game: TGame;
    79.   Graphics: TGraphics;
    80.  
    81. // ---------------------------------------------------------------------------
    82. // Ôóíêöèè ðèñîâàíèÿ
    83. // ---------------------------------------------------------------------------
    84. procedure DrawRect(hdc: HDC; x, y, w, h: Integer; color: COLORREF; filled: Boolean = True);
    85. var
    86.   br: HBRUSH;
    87.   pen: HPEN;
    88. begin
    89.   if filled then
    90.     br := CreateSolidBrush(color)
    91.   else
    92.     br := GetStockObject(NULL_BRUSH);
    93.   pen := CreatePen(PS_SOLID, 1, color);
    94.   SelectObject(hdc, pen);
    95.   SelectObject(hdc, br);
    96.   Rectangle(hdc, x, y, x + w, y + h);
    97.   DeleteObject(pen);
    98.   DeleteObject(br);
    99. end;
    100.  
    101. procedure DrawLine(hdc: HDC; x1, y1, x2, y2: Integer; color: COLORREF; width: Integer = 1);
    102. var
    103.   pen: HPEN;
    104.   oldPen: HPEN;
    105. begin
    106.   pen := CreatePen(PS_SOLID, width, color);
    107.   oldPen := SelectObject(hdc, pen);
    108.   MoveToEx(hdc, x1, y1, nil);
    109.   LineTo(hdc, x2, y2);
    110.   SelectObject(hdc, oldPen);
    111.   DeleteObject(pen);
    112. end;
    113.  
    114. procedure DrawCircle(hdc: HDC; x, y, radius: Integer; color: COLORREF; filled: Boolean = True);
    115. var
    116.   br: HBRUSH;
    117.   pen: HPEN;
    118. begin
    119.   if filled then
    120.     br := CreateSolidBrush(color)
    121.   else
    122.     br := GetStockObject(NULL_BRUSH);
    123.   pen := CreatePen(PS_SOLID, 1, color);
    124.   SelectObject(hdc, pen);
    125.   SelectObject(hdc, br);
    126.   Ellipse(hdc, x - radius, y - radius, x + radius, y + radius);
    127.   DeleteObject(pen);
    128.   DeleteObject(br);
    129. end;
    130.  
    131. // ---------------------------------------------------------------------------
    132. // Âñïîìîãàòåëüíûå ôóíêöèè
    133. // ---------------------------------------------------------------------------
    134. function IntToStr(i: Integer): string;
    135. begin
    136.   Str(i, Result);
    137. end;
    138.  
    139. function FloatToStr(f: Real): string;
    140. var
    141.   s: string;
    142. begin
    143.   Str(f:0:0, s);
    144.   Result := s;
    145. end;
    146.  
    147. function CarWidth(Kind: TCarKind): Integer;
    148. begin
    149.   if Kind = ckTruck then Result := 45 else Result := 30;
    150. end;
    151.  
    152. function CarHeight(Kind: TCarKind): Integer;
    153. begin
    154.   if Kind = ckTruck then Result := 45 else Result := 40;
    155. end;
    156.  
    157. function GetPlayerRect: TRect;
    158. begin
    159.   Result.Left   := Game.Player.X - 15;
    160.   Result.Top    := Game.Player.Y - 20;
    161.   Result.Right  := Game.Player.X + 15;
    162.   Result.Bottom := Game.Player.Y + 20;
    163. end;
    164.  
    165. function GetCarRect(const car: TCar): TRect;
    166. var
    167.   lane_width: Integer;
    168.   car_x: Integer;
    169. begin
    170.   lane_width := ROAD_WIDTH div 3;
    171.   car_x := Game.Road.Left + lane_width div 2 + car.Lane * lane_width;
    172.   Result.Left   := car_x - CarWidth(car.Kind) div 2;
    173.   Result.Top    := car.Y - CarHeight(car.Kind) div 2;
    174.   Result.Right  := car_x + CarWidth(car.Kind) div 2;
    175.   Result.Bottom := car.Y + CarHeight(car.Kind) div 2;
    176. end;
    177.  
    178. function CheckCollision(const r1, r2: TRect): Boolean;
    179. begin
    180.   Result := not ((r1.Right <= r2.Left) or (r1.Left >= r2.Right) or
    181.                  (r1.Bottom <= r2.Top) or (r1.Top >= r2.Bottom));
    182. end;
    183.  
    184. // ---------------------------------------------------------------------------
    185. // Èíèöèàëèçàöèÿ
    186. // ---------------------------------------------------------------------------
    187. procedure InitRoad(var Road: TRoad);
    188. begin
    189.   Road.Left := (SCREEN_WIDTH - ROAD_WIDTH) div 2;
    190.   Road.ScrollY := 0;
    191. end;
    192.  
    193. procedure InitPlayer(var Player: TPlayer);
    194. begin
    195.   Player.Lane := 1;
    196.   Player.X := SCREEN_WIDTH div 2;
    197.   Player.Y := SCREEN_HEIGHT - 80;
    198.   Player.MoveDelay := 0;
    199. end;
    200.  
    201. procedure InitCars(var Cars: TCars);
    202. begin
    203.   Cars.List := nil;
    204.   Cars.Count := 0;
    205. end;
    206.  
    207. procedure InitGameplay(var Gameplay: TGameplay);
    208. begin
    209.   Gameplay.Score := 0;
    210.   Gameplay.HighScore := 0;
    211.   Gameplay.Active := True;
    212.   Gameplay.Speed := 4.0;
    213.   Gameplay.CarTimer := 0;
    214. end;
    215.  
    216. procedure InitGraphics(var Graphics: TGraphics; hWnd: HWND);
    217. var
    218.   hdcWindow: HDC;
    219. begin
    220.   hdcWindow := GetDC(hWnd);
    221.   Graphics.hBitmap := CreateCompatibleBitmap(hdcWindow, SCREEN_WIDTH, SCREEN_HEIGHT);
    222.   Graphics.BufferDC := CreateCompatibleDC(hdcWindow);
    223.   Graphics.hOldBitmap := SelectObject(Graphics.BufferDC, Graphics.hBitmap);
    224.   ReleaseDC(hWnd, hdcWindow);
    225. end;
    226.  
    227. // ---------------------------------------------------------------------------
    228. // Èãðîâàÿ ëîãèêà
    229. // ---------------------------------------------------------------------------
    230. procedure UpdatePlayer;
    231. var
    232.   lane_width: Integer;
    233.   target_x: Integer;
    234. begin
    235.   with Game do
    236.   begin
    237.     if not Gameplay.Active then Exit;
    238.  
    239.     if Player.MoveDelay <= 0 then
    240.     begin
    241.       if (GetAsyncKeyState(VK_LEFT) and $8000) <> 0 then
    242.       begin
    243.         if Player.Lane > 0 then Dec(Player.Lane);
    244.         Player.MoveDelay := 10;
    245.       end
    246.       else if (GetAsyncKeyState(VK_RIGHT) and $8000) <> 0 then
    247.       begin
    248.         if Player.Lane < 2 then Inc(Player.Lane);
    249.         Player.MoveDelay := 10;
    250.       end;
    251.     end
    252.     else
    253.       Dec(Player.MoveDelay);
    254.  
    255.     lane_width := ROAD_WIDTH div 3;
    256.     target_x := Road.Left + lane_width div 2 + Player.Lane * lane_width;
    257.     Player.X := Player.X + Round((target_x - Player.X) * 0.2);
    258.   end;
    259. end;
    260.  
    261. procedure SpawnCar;
    262. var
    263.   i: Integer;
    264.   lanes_in_use: array[0..2] of Boolean;
    265.   available: array[0..2] of Integer;
    266.   avail_count: Integer;
    267.   lane: Integer;
    268.   car_kind: TCarKind;
    269. begin
    270.   with Game do
    271.   begin
    272.     if not Gameplay.Active then Exit;
    273.  
    274.     FillChar(lanes_in_use, SizeOf(lanes_in_use), 0);
    275.     for i := 0 to Cars.Count - 1 do
    276.       if Cars.List[i].Y < SCREEN_HEIGHT - 100 then
    277.         lanes_in_use[Cars.List[i].Lane] := True;
    278.  
    279.     avail_count := 0;
    280.     for i := 0 to 2 do
    281.       if not lanes_in_use[i] then
    282.       begin
    283.         available[avail_count] := i;
    284.         Inc(avail_count);
    285.       end;
    286.  
    287.     if avail_count > 0 then
    288.     begin
    289.       lane := available[Random(avail_count)];
    290.       if Random(2) = 0 then car_kind := ckCar else car_kind := ckTruck;
    291.  
    292.       SetLength(Cars.List, Cars.Count + 1);
    293.       Cars.List[Cars.Count].Lane := lane;
    294.       Cars.List[Cars.Count].Y := -Random(200) - 50;
    295.       Cars.List[Cars.Count].Kind := car_kind;
    296.       Inc(Cars.Count);
    297.     end;
    298.   end;
    299. end;
    300.  
    301. procedure UpdateCars;
    302. var
    303.   i: Integer;
    304.   player_rect, car_rect: TRect;
    305. begin
    306.   with Game do
    307.   begin
    308.     i := 0;
    309.     while i < Cars.Count do
    310.     begin
    311.       Cars.List[i].Y := Cars.List[i].Y + Round(Gameplay.Speed);
    312.  
    313.       if Cars.List[i].Y - 30 > SCREEN_HEIGHT then
    314.       begin
    315.         // óäàëÿåì ìàøèíó
    316.         Cars.List[i] := Cars.List[Cars.Count - 1];
    317.         Dec(Cars.Count);
    318.         SetLength(Cars.List, Cars.Count);
    319.         Gameplay.Score := Gameplay.Score + 10;
    320.         Continue;
    321.       end;
    322.  
    323.       if Gameplay.Active then
    324.       begin
    325.         player_rect := GetPlayerRect;
    326.         car_rect := GetCarRect(Cars.List[i]);
    327.         if CheckCollision(player_rect, car_rect) then
    328.         begin
    329.           Gameplay.Active := False;
    330.           if Gameplay.Score > Gameplay.HighScore then
    331.             Gameplay.HighScore := Gameplay.Score;
    332.         end;
    333.       end;
    334.  
    335.       Inc(i);
    336.     end;
    337.   end;
    338. end;
    339.  
    340. procedure UpdateGame;
    341. begin
    342.   with Game do
    343.   begin
    344.     if not Gameplay.Active then Exit;
    345.  
    346.     Gameplay.Speed := 4.0 + Gameplay.Score / 1500;
    347.     if Gameplay.Speed > 11.0 then Gameplay.Speed := 11.0;
    348.     Gameplay.Score := Gameplay.Score + 0.2;
    349.  
    350.     Inc(Gameplay.CarTimer);
    351.     if Gameplay.CarTimer > 30 + Round(30 - Gameplay.Score / 100) then
    352.     begin
    353.       if Gameplay.CarTimer > 60 - Round(Gameplay.Score / 100) then
    354.       begin
    355.         Gameplay.CarTimer := 0;
    356.         SpawnCar;
    357.       end;
    358.     end;
    359.  
    360.     UpdateCars;
    361.     UpdatePlayer;
    362.     Road.ScrollY := (Road.ScrollY + Round(Gameplay.Speed)) mod 40;
    363.   end;
    364. end;
    365.  
    366. procedure RestartGame;
    367. begin
    368.   InitRoad(Game.Road);
    369.   InitPlayer(Game.Player);
    370.   InitCars(Game.Cars);
    371.   InitGameplay(Game.Gameplay);
    372. end;
    373.  
    374. // ---------------------------------------------------------------------------
    375. // Îòðèñîâêà
    376. // ---------------------------------------------------------------------------
    377. procedure DrawRoad(hdc: HDC);
    378. var
    379.   i: Integer;
    380.   lane_width: Integer;
    381.   line_x: Integer;
    382.   y: Integer;
    383.   y_pos: Integer;
    384. begin
    385.   DrawRect(hdc, Game.Road.Left, 0, ROAD_WIDTH, SCREEN_HEIGHT, GRAY, True);
    386.   DrawLine(hdc, Game.Road.Left, 0, Game.Road.Left, SCREEN_HEIGHT, YELLOW, 4);
    387.   DrawLine(hdc, Game.Road.Left + ROAD_WIDTH, 0, Game.Road.Left + ROAD_WIDTH, SCREEN_HEIGHT, YELLOW, 4);
    388.  
    389.   lane_width := ROAD_WIDTH div 3;
    390.   for i := 1 to 2 do
    391.   begin
    392.     line_x := Game.Road.Left + i * lane_width;
    393.     y := -40;
    394.     while y < SCREEN_HEIGHT + 40 do
    395.     begin
    396.       y_pos := y + Game.Road.ScrollY;
    397.       if (y_pos >= 0) and (y_pos <= SCREEN_HEIGHT) then
    398.         DrawLine(hdc, line_x, y_pos, line_x, y_pos + 20, WHITE, 3);
    399.       Inc(y, 40);
    400.     end;
    401.   end;
    402. end;
    403.  
    404. procedure DrawCar(hdc: HDC; const car: TCar);
    405. var
    406.   x: Integer;
    407.   lane_width: Integer;
    408. begin
    409.   lane_width := ROAD_WIDTH div 3;
    410.   x := Game.Road.Left + lane_width div 2 + car.Lane * lane_width;
    411.  
    412.   if car.Kind = ckTruck then
    413.   begin
    414.     DrawRect(hdc, x - 22, car.Y - 22, 45, 45, BROWN, True);
    415.     DrawRect(hdc, x - 15, car.Y - 28, 30, 10, DARK_GRAY, True);
    416.   end
    417.   else
    418.   begin
    419.     DrawRect(hdc, x - 15, car.Y - 20, 30, 40, BLUE, True);
    420.     DrawRect(hdc, x - 12, car.Y - 25, 24, 15, DARK_GRAY, True);
    421.   end;
    422.   DrawRect(hdc, x - 17, car.Y - 12, 6, 12, BLACK, True);
    423.   DrawRect(hdc, x + 11, car.Y - 12, 6, 12, BLACK, True);
    424.   DrawRect(hdc, x - 17, car.Y + 8, 6, 12, BLACK, True);
    425.   DrawRect(hdc, x + 11, car.Y + 8, 6, 12, BLACK, True);
    426. end;
    427.  
    428. procedure DrawPlayerCar(hdc: HDC);
    429. var
    430.   x: Integer;
    431. begin
    432.   x := Game.Player.X;
    433.   DrawRect(hdc, x - 15, Game.Player.Y - 20, 30, 40, RED, True);
    434.   DrawRect(hdc, x - 12, Game.Player.Y - 25, 24, 15, RED, True);
    435.   DrawRect(hdc, x - 8, Game.Player.Y - 22, 6, 8, BLACK, True);
    436.   DrawRect(hdc, x + 2, Game.Player.Y - 22, 6, 8, BLACK, True);
    437.   DrawCircle(hdc, x - 14, Game.Player.Y - 10, 4, YELLOW, True);
    438.   DrawCircle(hdc, x + 14, Game.Player.Y - 10, 4, YELLOW, True);
    439.   DrawRect(hdc, x - 16, Game.Player.Y - 12, 6, 12, BLACK, True);
    440.   DrawRect(hdc, x + 10, Game.Player.Y - 12, 6, 12, BLACK, True);
    441.   DrawRect(hdc, x - 16, Game.Player.Y + 8, 6, 12, BLACK, True);
    442.   DrawRect(hdc, x + 10, Game.Player.Y + 8, 6, 12, BLACK, True);
    443. end;
    444.  
    445. procedure DrawUI(hdc: HDC);
    446. var
    447.   i: Integer;
    448.   color: COLORREF;
    449.   textBuf: string;
    450.   oldBkMode: Integer;
    451. begin
    452.   oldBkMode := SetBkMode(hdc, TRANSPARENT);
    453.  
    454.   textBuf := 'ÑרÒ: ' + FloatToStr(Int(Game.Gameplay.Score));
    455.   TextOut(hdc, 10, 10, PChar(textBuf), Length(textBuf));
    456.  
    457.   textBuf := 'ÐÅÊÎÐÄ: ' + FloatToStr(Int(Game.Gameplay.HighScore));
    458.   TextOut(hdc, 10, 50, PChar(textBuf), Length(textBuf));
    459.  
    460.   textBuf := 'ÑÊÎÐÎÑÒÜ: ' + FloatToStr(Round(Game.Gameplay.Speed * 25));
    461.   TextOut(hdc, 10, 90, PChar(textBuf), Length(textBuf));
    462.  
    463.   for i := 0 to 2 do
    464.   begin
    465.     if i = Game.Player.Lane then color := BLUE else color := DARK_GRAY;
    466.     DrawRect(hdc, SCREEN_WIDTH - 100 + i * 25, 20, 20, 40, color, True);
    467.     DrawRect(hdc, SCREEN_WIDTH - 100 + i * 25, 20, 20, 40, BLACK, False);
    468.   end;
    469.  
    470.   if not Game.Gameplay.Active then
    471.   begin
    472.     DrawRect(hdc, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, BLACK, True);
    473.     SetBkMode(hdc, TRANSPARENT);
    474.     SetTextColor(hdc, RED);
    475.     textBuf := 'GAME OVER';
    476.     TextOut(hdc, SCREEN_WIDTH div 2 - 100, SCREEN_HEIGHT div 2 - 60, PChar(textBuf), Length(textBuf));
    477.     SetTextColor(hdc, WHITE);
    478.     textBuf := 'Ñ÷¸ò: ' + FloatToStr(Int(Game.Gameplay.Score));
    479.     TextOut(hdc, SCREEN_WIDTH div 2 - 70, SCREEN_HEIGHT div 2, PChar(textBuf), Length(textBuf));
    480.     SetTextColor(hdc, YELLOW);
    481.     textBuf := 'Ðåêîðä: ' + FloatToStr(Int(Game.Gameplay.HighScore));
    482.     TextOut(hdc, SCREEN_WIDTH div 2 - 80, SCREEN_HEIGHT div 2 + 40, PChar(textBuf), Length(textBuf));
    483.     SetTextColor(hdc, WHITE);
    484.     textBuf := 'Íàæìè R äëÿ ðåñòàðòà';
    485.     TextOut(hdc, SCREEN_WIDTH div 2 - 120, SCREEN_HEIGHT div 2 + 100, PChar(textBuf), Length(textBuf));
    486.   end;
    487.  
    488.   SetBkMode(hdc, oldBkMode);
    489. end;
    490.  
    491. procedure Render(hdc: HDC);
    492. var
    493.   i: Integer;
    494. begin
    495.   DrawRect(hdc, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GREEN, True);
    496.   DrawRoad(hdc);
    497.   for i := 0 to Game.Cars.Count - 1 do
    498.     DrawCar(hdc, Game.Cars.List[i]);
    499.   DrawPlayerCar(hdc);
    500.   DrawUI(hdc);
    501. end;
    502.  
    503. // ---------------------------------------------------------------------------
    504. // Îêîííàÿ ïðîöåäóðà
    505. // ---------------------------------------------------------------------------
    506. function MainWndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
    507. var
    508.   ps: TPaintStruct;
    509.   hdcPaint: HDC;
    510. begin
    511.   case Msg of
    512.     WM_CREATE:
    513.       begin
    514.         Randomize;
    515.         InitRoad(Game.Road);
    516.         InitPlayer(Game.Player);
    517.         InitCars(Game.Cars);
    518.         InitGameplay(Game.Gameplay);
    519.         InitGraphics(Graphics, hWnd);
    520.         SetTimer(hWnd, ID_TIMER, TIMER_INTERVAL, nil);
    521.       end;
    522.  
    523.     WM_TIMER:
    524.       begin
    525.         if wParam = ID_TIMER then
    526.         begin
    527.           UpdateGame;
    528.           InvalidateRect(hWnd, nil, False);
    529.         end;
    530.       end;
    531.  
    532.     WM_PAINT:
    533.       begin
    534.         hdcPaint := BeginPaint(hWnd, ps);
    535.         Render(Graphics.BufferDC);
    536.         BitBlt(hdcPaint, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, Graphics.BufferDC, 0, 0, SRCCOPY);
    537.         EndPaint(hWnd, ps);
    538.       end;
    539.  
    540.     WM_KEYDOWN:
    541.       begin
    542.         if wParam = VK_ESCAPE then
    543.           PostQuitMessage(0);
    544.         if wParam = Ord('R') then
    545.           RestartGame;
    546.       end;
    547.  
    548.     WM_DESTROY:
    549.       begin
    550.         KillTimer(hWnd, ID_TIMER);
    551.         with Graphics do
    552.         begin
    553.           SelectObject(BufferDC, hOldBitmap);
    554.           DeleteDC(BufferDC);
    555.           DeleteObject(hBitmap);
    556.         end;
    557.         PostQuitMessage(0);
    558.       end;
    559.   else
    560.     Result := DefWindowProc(hWnd, Msg, wParam, lParam);
    561.     Exit;
    562.   end;
    563.   Result := 0;
    564. end;
    565.  
    566. // ---------------------------------------------------------------------------
    567. // Òî÷êà âõîäà
    568. // ---------------------------------------------------------------------------
    569. var
    570.   wc: TWndClass;
    571.   msg: TMsg;
    572. begin
    573.   FillChar(wc, SizeOf(wc), 0);
    574.   wc.style := CS_HREDRAW or CS_VREDRAW;
    575.   wc.lpfnWndProc := @MainWndProc;
    576.   wc.hInstance := HInstance;
    577.   wc.hbrBackground := GetStockObject(BLACK_BRUSH);
    578.   wc.lpszClassName := 'GameClass';
    579.   RegisterClass(wc);
    580.  
    581.   CreateWindow('GameClass', 'Game',
    582.     WS_OVERLAPPEDWINDOW or WS_VISIBLE,
    583.     200, 30, SCREEN_WIDTH, SCREEN_HEIGHT,
    584.     0, 0, HInstance, nil);
    585.  
    586.   while GetMessage(msg, 0, 0, 0) do
    587.   begin
    588.     TranslateMessage(msg);
    589.     DispatchMessage(msg);
    590.   end;
    591. end.
    Игра + исходники.
     

    Вложения:

    • Game_v1.rar
      Размер файла:
      16,4 КБ
      Просмотров:
      57
    Последнее редактирование: 14 июн 2026
  2. TrashGen

    TrashGen ТрещГен

    Публикаций:
    0
    Регистрация:
    15 мар 2011
    Сообщения:
    1.236
    Адрес:
    подполье
    >>Скорость игры постепенно растёт.

    Командир, мне надо в кусты срочно!
     
  3. Tech

    Tech Member

    Публикаций:
    0
    Регистрация:
    1 апр 2026
    Сообщения:
    47
    TrashGen, кстати будет и вторая часть игры.

    После того как поросенок Пётр успешно эмигрировал из России, он вдруг осознаёт, что мир вокруг - всего лишь симуляция.

    Как и Нео, Пётр после приема таблеток узнаёт что он Избранный. В новой стране оружие легализовано. Свинья без ружья - не свинья, поэтому теперь наш герой отстреливается от агентов Матрицы (красные враги), которые пытаются его «вернуть в систему».

    Для запуска игры на python: pip install pygame. Управление WASD как в кс.
    --- Сообщение объединено, 11 июн 2026 ---
    Сделал индикаторы здоровья. matrix_v2.
     

    Вложения:

    • matrix_v1.rar
      Размер файла:
      2,9 КБ
      Просмотров:
      54
    • matrix_v2.rar
      Размер файла:
      3,2 КБ
      Просмотров:
      49
    Последнее редактирование: 11 июн 2026
  4. TrashGen

    TrashGen ТрещГен

    Публикаций:
    0
    Регистрация:
    15 мар 2011
    Сообщения:
    1.236
    Адрес:
    подполье
    Здраствуйте. Я, TrashGen. Хотел бы чтобы вы сделали игру, 2Д-экшон суть такова... Пользователь может играть поросёнком Петром, собакой Марусей и Волком. И если пользователь играет поросёнком то поросёнок в тракторе, столбики дистанционные набигают граница России и волчата. Можно довить пограничников... И поросёнку раз тракторные то сделать так что там вокруг сраный трактор... А движок можно поставить так что вдали граница полоской, когда подходиш она преобразовываются в 3-хметровый забор. Можно морфировать в самолёт и т.п. управление WASD как в кс. И оружие легализовано тоже, и норкотеки тоже легалка. Можно шмыгать и т.п. Если играть за собаку Марусю то надо жрать конфеты и пить чай с поросёнком (имя я придумал) и его трактором, агентами Матрцы, и ходит на чай к комуто из этих (стул, крышка от кастрюли…). Ну а если за Волка… то значит со всеми удобствами или в кусты надо срочно, пользователь сам себе командир может делать что сам захочет прикажет своим военам дзена с ним самим написать такую игру и пойдет напишет за джва года.
    PS: Так же чтобы в игре могли не только нажраться таблеток и узнать, что он Избранный но и лишиться очков миграции и если пользователь не уйдёт в ондеграонд то его депортируют, так же "вернуться в систему" но пользователь может не продолжить играть а просто закрыть игру, или достать или купить ружьё, если выстрелить из него в ногу тоже либо умреш либо будеш ползать либо на коляске котаться, или самое хорошее… купить ружьё. Скорость игры постепенно растёт.…
     
  5. Tech

    Tech Member

    Публикаций:
    0
    Регистрация:
    1 апр 2026
    Сообщения:
    47
    TrashGen, вы описали четвертую(или пятую) ондеграондную версию. Мы еще только третюю выкатили.

    После перестрелки Пётр был укушен загадочным существом и обратился… в свинью-вампира(как в сумерках)!

    Теперь он не просто стреляет - он пьёт кровь врагов (вампиризм), уклоняется от пуль (вампирская ловкость)
    и наносит смертельные критические удары (укус вампира). За каждого убитого агента Пётр получает опыт.

    2026-06-11_23-56-56.png

    Есть выбор уровня сложности (жирнее враги, больше опыта).

    2026-06-11_23-57-14.png
     

    Вложения:

    • matrix_v3.rar
      Размер файла:
      2,8 МБ
      Просмотров:
      46
    Последнее редактирование: 12 июн 2026
  6. Tech

    Tech Member

    Публикаций:
    0
    Регистрация:
    1 апр 2026
    Сообщения:
    47
    Первая версия игры (ускользающий свин) с красным трактором на языке с.
     

    Вложения:

    • Game_v1_c.rar
      Размер файла:
      14,2 КБ
      Просмотров:
      48
    Последнее редактирование: 13 июн 2026
  7. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    15 окт 2022
    Сообщения:
    176
    Добавил трех-мерность в игру.

    2026-06-20_14-59-26.png
    1. Полноценный 3D рендеринг через рейкастинг
    2. Случайная генерация карты с комнатами и коридорами
    3. Враги с ИИ - преследуют и стреляют
    4. Система прокачки (вампиризм, уклонение, крит, здоровье, урон)
    5. Выбор сложности после каждого уровня
    --- Сообщение объединено, 20 июн 2026 в 16:31 ---
    Цель игры: пройти как можно больше уровней, убивая врагов, набирая опыт и прокачивая персонажа, прежде чем погибнуть.
    --- Сообщение объединено, 20 июн 2026 в 17:38 ---
    to do:
    - миникарта
    - рассово-чистая версия с мышиным обзором
     

    Вложения:

    • shooter_3d.rar
      Размер файла:
      7,3 КБ
      Просмотров:
      13
  8. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    15 окт 2022
    Сообщения:
    176
    В старых версиях нет x64. Напишите простой сорец на c, я переведу его на delphi и выложу бинарь (не знаю, что вы хотите в нем найти).
     
  9. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    491
    Раз пошла такая пьянка давайте сразу в окне сделаем четыре кнопки и сравним с тем что делает VS в x64-битном варианте.


    Код (C):
    1.  
    2. #include <windows.h>
    3.  
    4. //  Простое окно и четыре кнопки.
    5. //  В Делфи интересует именно компиляция в x64-битный EXE-формат.
    6.  
    7.  
    8. #define ID_BUTTON1 1001
    9. #define ID_BUTTON2 1002
    10. #define ID_BUTTON3 1003
    11. #define ID_BUTTON4 1004
    12.  
    13.  
    14. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    15.  
    16. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    17.     const char g_szClassName[] = "MyWindowClass";
    18.     WNDCLASSEXA wc;
    19.     HWND hwnd;
    20.     MSG Msg;
    21.  
    22.  
    23.     wc.cbSize        = sizeof(WNDCLASSEXA);
    24.     wc.style         = 0;
    25.     wc.lpfnWndProc   = WndProc;
    26.     wc.cbClsExtra    = 0;
    27.     wc.cbWndExtra    = 0;
    28.     wc.hInstance     = hInstance;
    29.     wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    30.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    31.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    32.     wc.lpszMenuName  = NULL;
    33.     wc.lpszClassName = g_szClassName;
    34.     wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    35.  
    36.     if (!RegisterClassExA(&wc)) {
    37.         MessageBoxA(NULL, "Не удалось зарегистрировать класс окна!", "Ошибка", MB_ICONEXCLAMATION | MB_OK);
    38.         return 0;
    39.     }
    40.  
    41.  
    42.     hwnd = CreateWindowExA(
    43.         WS_EX_CLIENTEDGE,
    44.         g_szClassName,
    45.         "Окно с 4 кнопками (Си -> ASM)",
    46.         WS_OVERLAPPEDWINDOW,
    47.         CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
    48.         NULL, NULL, hInstance, NULL
    49.     );
    50.  
    51.     if (hwnd == NULL) {
    52.         MessageBoxA(NULL, "Не удалось создать окно!", "Ошибка", MB_ICONEXCLAMATION | MB_OK);
    53.         return 0;
    54.     }
    55.  
    56.     ShowWindow(hwnd, nCmdShow);
    57.     UpdateWindow(hwnd);
    58.  
    59.  
    60.     while (GetMessage(&Msg, NULL, 0, 0) > 0) {
    61.         TranslateMessage(&Msg);
    62.         DispatchMessage(&Msg);
    63.     }
    64.     return (int)Msg.wParam;
    65. }
    66.  
    67.  
    68. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    69.     switch (msg) {
    70.         case WM_CREATE:
    71.  
    72.             CreateWindowExA(0, "BUTTON", "Кнопка 1", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
    73.                             20, 20, 150, 40, hwnd, (HMENU)ID_BUTTON1, (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
    74.            
    75.             CreateWindowExA(0, "BUTTON", "Кнопка 2", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
    76.                             20, 70, 150, 40, hwnd, (HMENU)ID_BUTTON2, (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
    77.            
    78.             CreateWindowExA(0, "BUTTON", "Кнопка 3", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
    79.                             20, 120, 150, 40, hwnd, (HMENU)ID_BUTTON3, (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
    80.            
    81.             CreateWindowExA(0, "BUTTON", "Кнопка 4", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
    82.                             20, 170, 150, 40, hwnd, (HMENU)ID_BUTTON4, (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
    83.             break;
    84.  
    85.         case WM_COMMAND:
    86.  
    87.             switch (LOWORD(wParam)) {
    88.                 case ID_BUTTON1:
    89.                     MessageBoxA(hwnd, "Вы нажали Кнопку 1", "Взаимодействие", MB_OK | MB_ICONINFORMATION);
    90.                     break;
    91.                 case ID_BUTTON2:
    92.                     MessageBoxA(hwnd, "Вы нажали Кнопку 2", "Взаимодействие", MB_OK | MB_ICONINFORMATION);
    93.                     break;
    94.                 case ID_BUTTON3:
    95.                     MessageBoxA(hwnd, "Вы нажали Кнопку 3", "Взаимодействие", MB_OK | MB_ICONINFORMATION);
    96.                     break;
    97.                 case ID_BUTTON4:
    98.                     MessageBoxA(hwnd, "Вы нажали Кнопку 4", "Взаимодействие", MB_OK | MB_ICONINFORMATION);
    99.                     break;
    100.             }
    101.             break;
    102.  
    103.         case WM_DESTROY:
    104.             PostQuitMessage(0);
    105.             break;
    106.  
    107.         default:
    108.             return DefWindowProc(hwnd, msg, wParam, lParam);
    109.     }
    110.     return 0;
    111. }
    112.  
     
  10. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    15 окт 2022
    Сообщения:
    176
    В старых версиях нет поддержки 64 :) Мне кажется тупая затея. Я использую delphi чтобы потом на другие языки прогр. переводить код(20 лет как). Не знаю что вы хотите 'доказать'. В delphi есть поддержка структур данных, из коробки хорошая ide, быстрая скорость разработки.
    Вот один из проектов с окном на WinApi с добавлением listview.
    Добавил ботам в игре немного мозгов.
     

    Вложения:

    • ListView.rar
      Размер файла:
      76,9 КБ
      Просмотров:
      13
    • engine_2d.rar
      Размер файла:
      6,5 КБ
      Просмотров:
      11
  11. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    15 окт 2022
    Сообщения:
    176
    2002 :)

    Новые версии delphi - уг. Я уже перешел на python.

    С появлением uac malvare кодинг умер, не знаю почему вы так фанатично
    упарываетесь размерами .exe. У вас/ваших клиентов до сих пор dial-up?

    Проводы_покойника.jpg
     
  12. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    15 окт 2022
    Сообщения:
    176
    Новая версия. Добавил снег, мини-карту, и ак 47.

    2026-06-21_12-32-13.png
    2026-06-21_12-37-06.png
     

    Вложения:

    Последнее редактирование: 21 июн 2026 в 12:44
    GRAFik нравится это.
  13. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.410
    Вот что-что, а UAC вообще никак не повлиял на жизнь или смерть малваре-кодинга.

    Вроде бы у эмбаркодеровцев был разговор, что они в более-менее современных версиях уже завезли LLVM-кодген, хотя (может быть) это было сделано только для таргетинга линуксов и маков. LLVM уже давно умеет в оптимизацию чуть ли не лучше, чем GCC со своим GIMPLE. f13nd (безусловно) бы всё равно обгуанил, но в целом если в новых версиях использовать LLVM, кодген должен быть куда лучше.

    В целом да, но иногда смотришь на то, как работает некоторый современный модный молодежный софт, и понимаешь, что лучше бы они все-таки упарывались размером экзешников, качеством кода и тд. А то тормозит как ппц, жрет память как не в себя, еще и то и дело падает, несмотря на то, что не на Цэ написан.

    Умение отключать и жить без стандартных библиотек нужен не только для этого. Например, если ты внезапно захотел shell-код собрать из ЯВУ. Или, например, запустить код на ЯВУ без операционной системы, или на какой-то сильно урезанной железке. Если ты с такими задачами не сталкиваешься, не означает, что их нет, не все занимаются шлепаньем формочек, так бывает. Ну и есть задачи, в которых качество кодгена и скорость кода имеют значение, например, геймдев, всяческие симуляции в индустрии, микросервисы, которые должны молотить цифорки чем быстрее, тем лучше, и так далее.
     
  14. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    491
    Rel, так пропагандировать нужно лучше, объяснять людям - что такое CLANG/LLVM? Глядишь, народ и потянется к знаниям. Да, Фаинд класный специаалист по части FASM (и то, по-моему, только в 32-х битной его части) и многим фишкам в системном программировании, но вот по части CLANG/LLVM - не хватает у человека знаний ( и у меня, кстати, тоже :) ). Нужно доходчиво объяснять и рассказывать людям, что CLANG/LLVM - это, в целом - классная технология и в неё вложили много денег, технологий и знаний. И так, глядишь, потихоньку - народ начнёт приобщаться к этому делу. А без рекламы и пропаганды (вот хотя бы даже от вас) дело с мертвой точки не сдвинется. :)
     
    Последнее редактирование: 21 июн 2026 в 14:45
  15. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.410
    Ну, начнем с того, что ему это не нужно, ровно также, как мне не нужен его драгоценный и единственно-рассово-верный фасм, а полемика на форумах - это уже лет 20, как привычная для всех вещь. Вряд ли имеет смысл что-то тут менять, всех всё устраивает. Да и чтобы "доходчиво рассказать людям", что там в LLVM/Clang к чему, нужно простыни текста писать (типа Индиных ТТР7131, нагаллюцинированных чат-ботом), которые, собственно, никто и читать не будет. Ну и да, у меня не то чтобы прям достаточно знаний, чтобы за каждую около-ллвмную вещь вписываться, я же магл.
     
  16. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    2.219
    Я не утверждал никогда, что фасм самый лучший, просто у него есть ряд преимуществ, которые не-маглам могут пригодиться.
    Ну да. "Кодогенерация слаба? Обнови гцц, еще сильней обнови, ну прям очень сильно обнови, должно помочь". Примерно такого рода знания.
     
  17. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.410
    Ты ставишь гцц, которым пользовался еще моисей, и даже не понятно, на каких архиологических раскопках ты его откопал, не включаешь оптимизацию и идешь орать на форум, что кодогенерация гуан, а потом не доволен, что тебе говорят твой гцц обновить и включить оптимизацию? Какого совета еще ты ожидал то? Что тебе начнут внутреннее устройства компилятора объяснять, когда ты не сподобился аргументы командной строки посмотреть, прежде чем на форуме орать?
     
  18. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    2.219
    Опять эта сказка про белого бычка. Во-первых как выяснилось, что гцц Моисея Лазаревича, что гцц Лазаря Моисеевича байт в байт одно и то же генерируют. Во-вторых -o0 опция по умолчанию. Причем не только в самом gcc, но и в ide. Много ли аленей ее включат, особенно если не смотрят бинарник и даже если бы знали как посмотреть ничего не поняли бы? Или "включать оптимизацию" 4 года в универе учат? Про качество этой оптимизации опять же есть во что макнуть.
     
  19. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.410
    Ну ты не включил, так что как максимум: общее количество аленей минус один.

    Ну мы же уже это проходили. По умолчанию для многих компиляторов принят режим без оптимизации для упрощения отладки, это во-первых. А во-вторых, многие компиляторы таки предполагают, что программисту может понадобится тонкая настройка оптимизаций кода, и давать какую-то дефолтную оптимизацию для Цэ и Плюсов мало смысла. Ну и в третьих, на первом курсе универа на первом же занятии по Цэ я узнал, что настройки оптимизации есть, и что ее нужно включать, если она тебе нужна.

    Ты можешь что угодно макнуть во что угодно, даже не понимая сути, это давно понятно, можно об этом постоянно не напоминать. Но разработчик в целом не рассматривает частные случаи оптимизации, он не выдирает отдельные фрагменты кода, чтобы на их примере обгуанить кодген, он рассматривает ботлнеки в производительности приложения и оптимизирует их.
     
  20. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    2.219
    Убунта. -o0. Как-то умозрительно это у тебя работает. На практике П - Профессионалы оптимизацию не включают. И может быть гцц сам по себе не такое уж и гавно, но с поправками на реальность выходит, что гавно.
    Код (Text):
    1. .text:000000000001C657 0F B6 54 24 60    movzx   edx, [rsp+0B8h+var_58]
    2. .text:000000000001C65C 80 FA 20          cmp     dl, 20h
    3. .text:000000000001C65F 0F 87 33 03 00 00 ja      def_1C66F
    4. .text:000000000001C665 0F B6 C2          movzx   eax, dl