📄 unit_classes.pas
字号:
procedure TGameWidget.keyPressed(Key: TGameKey);
begin
case ( Key ) of gkKey_Left: begin //showmessage('left'); if (m_state = gsPlaying)or(m_state = gsLevelCompleted)or ((m_state = gsDying)and(m_counter > 8)) then begin m_player_dir := gdLeft; m_player_req_x := 0; end; end; gkKey_Right: if (m_state = gsPlaying)or(m_state = gsLevelCompleted)or ((m_state = gsDying)and(m_counter > 8)) then begin m_player_dir := gdRight; m_player_req_x := paintBox.width - 16; end; gkKey_Up, gkKey_Fire, gkKey_Down: if (m_state = gsPlaying)or(m_state = gsLevelCompleted) then fireBullet() else if (m_state <> gsDying) then start(); gkKey_Start: if (m_state = gsPlaying)or(m_state = gsLevelCompleted) then pause() else if (m_state <> gsDying) then unpause(); end;
end;
procedure TGameWidget.keyReleased(Key: TGameKey);
begin
case ( Key ) of
gkKey_Left, gkKey_Right: begin m_player_dir := gdNone; m_player_req_x := m_player_x; end; end;
end;
procedure TGameWidget.mouseMove(mouseX, mouseY: integer);
var
max_req_x, req_x: integer;
begin
if (m_state = gsPlaying)or(m_state = gsLevelCompleted)or
((m_state = gsDying)and(m_counter > 8)) then
begin
max_req_x := paintBox.Width - 16; req_x := mouseX - 8; if (req_x < 0) then begin req_x := 0; end else if (req_x > max_req_x) then begin req_x := max_req_x; end; m_player_req_x := req_x; if (req_x < m_player_x) then begin m_player_dir := gdLeft; end else if (req_x > m_player_x) then begin m_player_dir := gdRight; end else begin m_player_dir := gdNone; end; end;end;
procedure TGameWidget.newLevel;
var
i: integer;
begin
m_num_diving := 0;
m_alien_counter := 0; m_aliens := 0; for i := 0 to max_aliens-1 do begin m_alien_xhome[m_aliens] := (i mod 10) * 20 + 10 + ((i div 10) mod 2) * 20; m_alien_yhome[m_aliens] := -16 - (i div 10) * 20; m_alien_statehome[m_aliens] := (i div 10) mod 2; m_alien_x[m_aliens] := m_alien_xhome[m_aliens]; m_alien_y[m_aliens] := m_alien_yhome[m_aliens]; m_alien_state[m_aliens] := m_alien_statehome[m_aliens]; m_aliens := m_aliens+1; end;
end;
procedure TGameWidget.pause;
begin
timer.Enabled := False;
end;
procedure TGameWidget.rePaint(flag: boolean);
begin
case (m_state) of
gsIntro: drawIntro(); gsPlaying, gsDying, gsLevelCompleted: drawPlaying(); gsGameOver: drawGameOver(); end;
end;
procedure TGameWidget.setSpeed(speed: integer);
begin
timer.Interval := 120 - speed;
end;
procedure TGameWidget.start;
var
max_y, i: integer;
begin
Randomize;
max_y := paintBox.Height;
m_state := gsPlaying; m_counter := 0; m_alien_counter := 0; m_player_dir := gdNone; m_player_x := ( paintBox.width - 16) div 2; m_player_req_x := m_player_x; m_bullets_fired := 0; m_aliens_killed := 0; m_level := 1; m_score := 0; m_lives := 3; m_num_diving := 0; m_bullets := 0; m_missiles := 0; m_aliens := 0; m_stars := 0; for i := 0 to max_stars-1 do begin m_star_x[m_stars] := random(32767) mod 240; m_star_y[m_stars] := random(32767) mod max_y; m_star_speed[m_stars] := (random(32767) mod 16) + 1; m_star_size[m_stars] := random(32767) mod 16; m_stars := m_stars+1; end; newLevel(); repaint(false);
end;
procedure TGameWidget.stop;
begin
switchState(gsIntro);
repaint(false);
end;
procedure TGameWidget.switchState(state: TGameState);
begin
if (m_state <> state) then
begin
m_state := state; m_counter := 0; end;
end;
procedure TGameWidget.timerTick( Sender: TObject );
begin
m_counter := m_counter+1;
m_alien_counter := m_alien_counter+1; case (m_state) of gsIntro:; gsPlaying: { if (m_mouse_down) then begin m_mouse_counter := m_mouse_counter+1; if (m_mouse_counter > 5) then begin fireBullet(); m_mouse_counter := 0; end; end;} updateLevel(); gsDying: begin updateLevel(); if (m_counter >= 60) then begin m_lives := m_lives-1; if (m_lives = 0) then switchState(gsGameOver) else switchState(gsPlaying); end; end; gsLevelCompleted: begin updateLevel(); if (m_counter >= 60) then begin m_level := m_level+1; //M for 30 level if (m_level > 30) then begin m_state := gsGameOver; switchState(gsGameOver); end else begin newLevel(); switchState(gsPlaying); end; //M end. end; end; gsGameOver: if (m_counter >= 600) then switchState(gsIntro); end; repaint(false);
end;
procedure TGameWidget.unpause;
begin
timer.Enabled := True;
end;
procedure TGameWidget.updateLevel;
var
max_x, max_y: integer;
i, j, tmp, flag: integer;
label retry_aliens, retry_bullets, retry_missiles;
begin
max_y := paintBox.Height;
max_x := paintBox.Width - 16; // move player to new position if (m_player_dir = gdLeft) then begin m_player_x := m_player_x - 6; if (m_player_x <= m_player_req_x) then begin m_player_x := m_player_req_x; m_player_dir := gdNone; end; end else if (m_player_dir = gdRight) then begin m_player_x := m_player_x + 6; if (m_player_x >= m_player_req_x) then begin m_player_x := m_player_req_x; m_player_dir := gdNone; end; end; // move bullets to new positions for i := 0 to m_bullets-1 do begin m_bullet_y[i] := m_bullet_y[i] - 12; if (m_bullet_y[i] <= -16) then deleteBullet(i); end; // move missiles to new positions for i := 0 to m_missiles-1 do begin m_missile_y[i] := m_missile_y[i] + 9; if (m_missile_y[i] >= max_y) then deleteMissile(i); end; // move stars to new position for i := 0 to m_stars-1 do begin m_star_y[i] := m_star_y[i] + m_star_speed[i]; if (m_star_y[i] >= max_y) then begin m_star_x[i] := random(32767) mod 240; m_star_y[i] := 0; m_star_speed[i] := (random(32767) mod 16) + 1; m_star_size[i] := random(32767) mod 16; end; end; { in shooting mode, they move left/right and down until they reach * their initial y position. then they only move left/right. * in marching mode, they constantly move left/right and down at * the end of each sweep, and their speed rises } if (m_mode = gmShooting) then begin for i := 0 to m_aliens -1 do begin if (m_alien_state[i] < 2) then begin // normal state, moving down to yhome + 60, then swooping and diving if (m_alien_y[i] < (m_alien_yhome[i] + 60)) then begin m_alien_y[i] := m_alien_y[i]+1; end else if (((random(32767) mod ((33 * m_aliens) div m_level)) = 0) and( m_num_diving < ((m_level + 5)div 3))) then begin m_alien_state[i] := 2; m_num_diving := m_num_diving+1; continue; end else if (m_aliens < (4 + m_level div 4)) then begin m_alien_state[i] := 2; m_num_diving := m_num_diving+1; continue; end else if ((random(32767) mod ((33 * m_aliens) div m_level)) = 0) then begin fireMissile(i); end; tmp := (m_alien_counter + m_alien_statehome[i] * 20) mod 40; if (tmp < 20) then begin m_alien_x[i] := m_alien_xhome[i] + tmp - m_alien_statehome[i] * 20; end else begin m_alien_x[i] := m_alien_xhome[i] + 20 - (tmp mod 20) - m_alien_statehome[i] * 20; end end else if (m_alien_state[i] < 4) then begin // diving state, dive to bottom of screen, then return home if (m_alien_state[i] = 2) then begin m_alien_x[i] := m_alien_x[i] - 3; if (m_alien_x[i] <= 0) then begin m_alien_state[i] := 3; m_alien_x[i] := 0; end end else begin m_alien_x[i] := m_alien_x[i] + 3; if (m_alien_x[i] >= max_x) then begin m_alien_state[i] := 2; m_alien_x[i] := max_x; end end; if (m_alien_y[i] > (max_y div 2)) then begin if (m_alien_x[i] > m_player_x) then begin m_alien_state[i] := 2; end else if (m_alien_x[i] < m_player_x) then begin m_alien_state[i] := 3; end end else begin if ((m_alien_counter mod 5) = 0) then begin if (m_alien_state[i] = 2) then begin m_alien_state[i] := 3; end else begin m_alien_state[i] := 2; end end end; m_alien_y[i] := m_alien_y[i] + 6; if (m_alien_y[i] >= max_y) then begin m_alien_x[i] := m_alien_xhome[i]; m_alien_y[i] := m_alien_yhome[i]; m_alien_state[i] := m_alien_statehome[i]; m_num_diving := m_num_diving-1; end else if ((m_alien_y[i] < (max_y - 48)) and ((random(32767) mod ((100 * m_aliens) div m_level)) = 0)) then begin fireMissile(i); end; end; end; end else begin flag := 0; if (m_aliens < (4 + m_level div 4)) then begin flag := 1; end; for i := 0 to m_aliens-1 do begin if (m_alien_state[i] > 3) then begin continue; end; if (m_alien_y[i] > (max_y + 60)) then begin flag := 2; break; end else if (m_alien_y[i] >= (max_y div 2 - 16)) then begin flag := 1; end; end; if (flag = 2) then begin for i := 0 to m_aliens-1 do begin if (m_alien_state[i] > 3) then begin continue; end; m_alien_x[i] := m_alien_xhome[i]; m_alien_y[i] := m_alien_yhome[i]; m_alien_state[i] := m_alien_statehome[i]; end; m_alien_counter := 0; end; for i := 0 to m_aliens-1 do begin if (m_alien_state[i] > 3) then begin continue; end; if (flag = 1)or( (m_alien_y[i] < (m_alien_yhome[i] + 60))) then begin m_alien_y[i] := m_alien_y[i] + 1 + flag; end else if ((m_alien_counter mod 20) = 0) then begin m_alien_y[i] := m_alien_y[i] + ((m_alien_counter - 60) div 40) + 2; end else if ((random(32767) mod ((33 * m_aliens) div m_level)) = 0) then begin fireMissile(i); end; tmp := (m_alien_counter + m_alien_statehome[i] * 20) mod 40; if (tmp < 20) then begin m_alien_x[i] := m_alien_xhome[i] + tmp - m_alien_statehome[i] * 20; end else begin m_alien_x[i] := m_alien_xhome[i] + 20 - (tmp mod 20) - m_alien_statehome[i] * 20; end; end end;retry_aliens: for i := 0 to m_aliens-1 do begin if (m_alien_state[i] > 12) then begin deleteAlien(i); goto retry_aliens; end else if (m_alien_state[i] > 3) then begin m_alien_state[i] := m_alien_state[i]+1; end end;retry_bullets: for i := 0 to m_bullets-1 do begin for j := 0 to m_aliens-1 do begin if (m_alien_state[j] < 4 )and( abs(m_alien_x[j] - m_bullet_x[i]) < 12) and (abs(m_alien_y[j] - m_bullet_y[i]) < 12) then begin if (m_alien_state[j] > 1) then begin m_num_diving := m_num_diving-1; end; addScore((m_alien_state[j] div 2 + 1) * 25); m_alien_state[j] := 4; deleteBullet(i); goto retry_bullets; end; end end;retry_missiles: for i := 0 to m_missiles-1 do begin if (abs(max_y - 32 - m_missile_y[i]) < 12)and(abs(m_player_x - m_missile_x[i]) < 12) then begin switchState(gsDying); deleteMissile(i); goto retry_missiles; end end; for i := 0 to m_aliens-1 do begin if (m_alien_state[i] < 4)and( abs(max_y - 32 - m_alien_y[i]) < 12 ) and( abs(m_player_x - m_alien_x[i]) < 12) then begin switchState(gsDying); if (m_alien_state[i] > 1) then begin m_num_diving := m_num_diving-1; end; m_alien_state[i] := 4; break; end; end; if (m_state <> gsDying)and( m_state <> gsLevelCompleted)and(m_aliens <= 0) then begin switchState(gsLevelCompleted); addScore(250); end;
end;
procedure TGameWidget.updateMode(mode: TGameModes);
begin
case (mode) of
gmShooting: if (m_mode <> gmShooting) then begin m_mode := gmShooting; if (m_state = gsPlaying) or (m_state = gsDying) or (m_state = gsLevelCompleted) then start(); end; gmMarching: if (m_mode <> gmMarching) then begin m_mode := gmMarching; if (m_state = gsPlaying) or (m_state = gsDying) or (m_state = gsLevelCompleted) then start(); end; end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -