improve cpu movement in pong - aliensoldier - 01-26-2024
I have programmed the movement in a very simple way for the player cpu following the ball, I would like some tips to improve the movement and make it seem more intelligent, and make it more fun to play.
I share all the code, the movement is in the player_cpu.move method of player_cpu:
Code: 'pong
include "player.n7"
include "player-cpu.n7"
include "ball.n7"
set window "example pong",640,480,false
set redraw off
'objeto-----------------------------------
player = Player()
ball = Ball()
player_cpu = Player_Cpu()
while not keydown(KEY_ESCAPE,true)
set color 0,0,0
cls
'objetos-----------------------------
player.update()
player.Draw()
player_cpu.update(ball)
player_cpu.Draw()
ball.update(player,player_cpu)
ball.Draw()
'lineas para el fondo------------------
'draw rect 320,32,2,60,true
'draw rect 320,120,2,60,true
'draw rect 320,210,2,60,true
'draw rect 320,300,2,60,true
'draw rect 320,390,2,60,true
'draw line 320,32,320,460
'draw line 330,32,330,460
redraw
fwait 60
wend
Code: 'player
function Player()
player = []
player.Width = 20
player.Height = 100
player.x = 32 - player.Width/2
player.y = 240 - player.Height/2
player.speed = 5
player.live = true
player.update = function()
if this.live = true
this.move()
endif
endfunc
player.Draw = function()
if this.live = true
set color 255,0,205
draw rect this.x,this.y,this.Width,this.Height,true
endif
endfunc
player.move = function()
if keydown(KEY_UP,false) and this.y > 16
this.y = this.y - this.speed
elseif keydown(KEY_DOWN,false) and this.y < 370
this.y = this.y + this.speed
endif
endfunc
return player
endfunc
Code: 'player-cpu
function Player_Cpu()
player_cpu = []
player_cpu.Width = 20
player_cpu.Height = 100
player_cpu.x = 608 - player_cpu.Width/2
player_cpu.y = 240 - player_cpu.Height/2
player_cpu.speed = 5
player_cpu.live = true
'player_cpu.ball = ball
player_cpu.update = function(ball)
if this.live
this.move(ball)
endif
endfunc
player_cpu.Draw = function()
if this.live
set color 255,204,0
draw rect this.x,this.y,this.Width,this.Height,true
endif
endfunc
player_cpu.move = function(ball)
if this.y > ball.y and this.y > 16
this.y = this.y - this.speed
endif
if this.y < ball.y and this.y < 370
this.y = this.y + this.speed
endif
endfunc
return player_cpu
endfunc
Code: 'ball
include "miscellaneous.n7"
function Ball()
ball = []
ball.Width = 16
ball.Height = 16
ball.x = 320 - ball.Width / 2
ball.y = 240 - ball.Height / 2
ball.speedX = 2
ball.speedY = 2
ball.live = true
'ball.player = player
ball.update = function(player,player_cpu)
if this.live = true
this.move()
this.bounce()
this.collision_player(player)
this.collision_player_cpu(player_cpu)
endif
endfunc
ball.Draw = function()
if this.live = true
set color 200,200,200
draw rect this.x,this.y,this.Width,this.Height,true
'draw ellipse this.x,this.y,9,9,true
endif
endfunc
ball.move = function()
this.x = this.x + this.speedX
this.y = this.y + this.speedY
endfunc
ball.bounce = function()
if this.x <= 0 or this.x >= 640
this.speedX = this.speedX * -1
endif
if this.y <= 0 or this.y >= 480
this.speedY = this.speedY * -1
endif
endfunc
ball.collision_player = function(player)
'colision con la x
if collision_rect(this.x+this.speedX,this.y,this.Width,this.Height,player.x,player.y,player.Width,player.Height)
this.speedX = this.speedX * -1
endif
'colision con la y
if collision_rect(this.x,this.y+this.speedY,this.Width,this.Height,player.x,player.y,player.Width,player.Height)
this.speedY = this.speedY * -1
endif
endfunc
ball.collision_player_cpu = function(player_cpu)
'colision con la x
if collision_rect(this.x+this.speedX,this.y,this.Width,this.Height,player_cpu.x,player_cpu.y,player_cpu.Width,player_cpu.Height)
this.speedX = this.speedX * -1
endif
'colision con la y
if collision_rect(this.x,this.y+this.speedY,this.Width,this.Height,player_cpu.x,player_cpu.y,player_cpu.Width,player_cpu.Height)
this.speedY = this.speedY * -1
endif
endfunc
return ball
endfunc
Code: 'miscellaneous
'variables y funciones para manejar los puntos
visible score_player = 0
visible score_player_cpu = 0
function get_score_player()
return score_player
endfunc
function get_score_player_cpu()
return score_player_cpu
endfunc
'funcion de colision--------------------------------
function collision_rect(x1,y1,w1,h1,x2,y2,w2,h2)
return x1 + w1 > x2 and x1 < x2 + w2 and
y1 + h1 > y2 and y1 < y2 + h2
endfunc
RE: improve cpu movement in pong - Marcus - 01-26-2024
In most cases, making a computer opponent seem human is about making it more stupid - make it do stupid little moves, make pauses etc
Johnno posted a pong on the forum written in n7. I think it was based on something I wrote in n6. So I'll post the n6 source code here. I just tried it, and the computer really does make silly little moves and pauses - making it seem more human.
Code: rem ==================================================================
rem Pong, from basicprogramming.org.
rem
rem By Marcus Johansson.
rem ==================================================================
import "Speed.lib"
set window 0, 0, 320, 240, false, 2
set redraw off
plyX = 8
comX = 320 - 24
comY# = 120.0
comWantedY# = 120.0
comTimer = 25
hasBall = 1
ballX#
ballY#
ballDX#
ballDY#
ballSpeed# = 3.0
comScore = 0
plyScore = 0
do
plyY = mousey()
if hasBall = 1
ballX# = float(plyX + 16)
ballY# = float(plyY - 4)
if mousebutton(0)
ballDX = 1.0
ballDY = 0.0
ballSpeed = 2.0
hasBall = 0
endif
elseif hasBall = 2
ballX = float(comX - 8)
ballY = comY - 4.0
else
ballX = ballX + ballDX*ballSpeed
ballY = ballY + ballDY*ballSpeed
if ballY < 0.0
ballY = 0.0
ballDY = -ballDY
elseif ballY# > 240.0 - 8.0
ballY = 240.0 - 8.0
ballDY = -ballDY
endif
if ballDX < 0.0
if RectsOverlap(plyX, plyY - 24, 16, 48, int(ballX), int(ballY), 8, 8)
dy# = (ballY - float(plyY))/64.0
dx# = 0.5
k# = 1.0/sqr(dx*dx + dy*dy)
ballDX# = k*dx
ballDY# = k*dy
ballSpeed = min#(ballSpeed*1.1, 6.0)
endif
else
if RectsOverlap(comX, int(comY) - 24, 16, 48, int(ballX), int(ballY), 8, 8)
dy# = (ballY - comY)/64.0
dx# = -0.5
k# = 1.0/sqr(dx*dx + dy*dy)
ballDX# = k*dx
ballDY# = k*dy
ballSpeed = min#(ballSpeed*1.1, 6.0)
endif
endif
if ballX > 320.0
hasBall = 1
plyScore = plyScore + 1
elseif ballX < -8.0
hasBall = 2
comTimer = 50
comWantedY = float(rnd(240))
comScore = comScore + 1
endif
endif
comTimer = comTimer - 1
if comTimer <= 0
if hasBall = 1
comWantedY = ballY - 16.0 + float(rnd(32)) + (float(comX) - ballX)/ballSpeed*ballDY
comTimer = comTimer + 25 + rnd(25)
elseif hasBall = 2
hasBall = 0
ballDX = -1.0
ballDY = 0.0
ballSpeed = 2.0
else
comWantedY = ballY - 20.0 + float(rnd(40)) + (float(comX) - ballX)/ballSpeed*ballDY
if ballDX < 0.0
comTimer = comTimer + 20 + rnd(20)
else
comTimer = comTimer + 6 + rnd(6)
endif
endif
endif
comY = 0.90*comY + 0.1*comWantedY
set color 0, 0, 0
cls
set color 255, 255, 255
for y = 0 to 29
draw rect 160 - 2, y*8 + 2, 4, 4, true
next
draw rect plyX, plyY - 24, 16, 48, true
draw rect comX, int(comY) - 24, 16, 48, true
draw rect int(ballX), int(ballY), 8, 8, true
set caret 16, 8
center plyScore
set caret 320 - 16, 8
center comScore
redraw
proc SPD_HoldFrame(60)
until keydown(27) or not running()
function RectsOverlap(x0, y0, w0, h0, x1, y1, w1, h1)
if x0 + w0 < x1 then return false
if y0 + h0 < y1 then return false
if x1 + w1 < x0 then return false
if y1 + h1 < y0 then return false
return true
endfunc
RE: improve cpu movement in pong - johnno56 - 01-26-2024
Certainly is a "golden oldie"... Gotta love the classics...
RE: improve cpu movement in pong - aliensoldier - 01-26-2024
It seems that if I increase the speed of the cpu player, instead of moving faster, it becomes more clumsy, some way to make it move faster and make it more difficult to place the ball on it.
|