pong.py

Created by laigna

Created on March 14, 2026

3.3 KB

Simple pong


# Pong - NumWorks
# Created by Alvar Laigna - https://alvarlaigna.com
# Up/Down:paddle OK:serve/restart Back:quit
from kandinsky import fill_rect as F,draw_string as D
from ion import keydown as K
from time import sleep as Z,monotonic as M
W,H=320,222
BK=(0,)*3;WH=(255,)*3
P1C=(80,160,255);P2C=(255,100,80)
BC=(0,255,100);DC=(30,)*3

okv=1 if K(4)or K(52) else 0

def okd():
 return K(4)or K(52)

def okp():
 global okv
 d=okd()
 if d and not okv:
  okv=1
  return True
 if not d:okv=0
 return False

def wup():
 while okd():Z(0.02)
 Z(0.12)

def title():
 F(0,0,W,H,BK)
 D("P O N G",112,30,(0,255,100),BK)
 D("- - - - - - - - - - -",50,55,DC,BK)
 D("You",20,80,P1C,BK);D("vs",150,80,WH,BK);D("CPU",260,80,P2C,BK)
 D("Up / Down",100,115,(180,)*3,BK)
 D("move paddle",95,135,(120,)*3,BK)
 D("OK = serve & restart",60,165,(180,)*3,BK)
 D("Back = quit",105,185,(120,)*3,BK)
 D("Press OK",125,206,(0,255,100),BK)
 while True:
  if okp():wup();return
  if K(17):return False
  Z(0.05)

def serve(s1,s2):
 # Draw center score big
 F(100,85,120,35,BK)
 D(str(s1),135,90,(80,160,255),BK)
 D("-",155,90,DC,BK)
 D(str(s2),170,90,(255,100,80),BK)
 Z(0.6)
 for c in("3","2","1"):
  F(155,115,10,18,BK)
  D(c,155,115,(0,255,100),BK)
  Z(0.5)
 F(100,85,120,65,BK)

def drawfield(s1,s2):
 F(0,0,W,H,BK)
 # Dashed center line
 for i in range(0,H,8):F(W//2,i,1,4,DC)
 # Score at top
 D(str(s1),W//2-25,2,P1C,BK)
 D(str(s2),W//2+15,2,P2C,BK)
 # Goal markers
 D("7",5,2,(50,)*3,BK)
 D("7",W-15,2,(50,)*3,BK)

def flash(px,py,c):
 F(px,py,5,30,WH)
 Z(0.03)
 F(px,py,5,30,c)

def pong():
 if title()==False:return
 p1=p2=H//2-15
 bx,by=float(W//2),float(H//2)
 vx,vy=0.0,0.0
 s1=s2=0;paused=True
 drawfield(s1,s2)
 while True:
  if K(17):return
  # Erase
  F(6,int(p1),5,30,BK);F(W-11,int(p2),5,30,BK)
  F(int(bx)-1,int(by)-1,7,7,BK)
  # P1 input
  if K(1)and p1>2:p1-=4
  if K(2)and p1<H-32:p1+=4
  if paused:
   F(6,int(p1),5,30,P1C);F(W-11,int(p2),5,30,P2C)
   F(int(bx),int(by),5,5,BC)
   if okp():
    serve(s1,s2)
    drawfield(s1,s2)
    bx,by=float(W//2),float(H//2)
    vx=3.5 if s1<=s2 else-3.5;vy=2.0
    paused=False
   Z(0.02);continue
  # AI
  sp=min(3.5,2.0+(s1+s2)*0.15)
  pred=by+vy*((W-20-bx)/max(abs(vx),0.1)if vx>0 else 99)
  t=max(0,min(H-30,pred-15))
  if p2<t-2:p2=min(p2+sp,H-30)
  elif p2>t+2:p2=max(p2-sp,0)
  # Ball
  bx+=vx;by+=vy
  if by<1:by=1.0;vy=abs(vy)
  if by>H-6:by=float(H-6);vy=-abs(vy)
  # Paddle hits
  hit=False
  if vx<0 and 6<bx<14 and p1-5<by<p1+30:
   vx=abs(vx)+0.15;vy+=(by-p1-13)/5
   hit=True;flash(6,int(p1),P1C)
  if vx>0 and W-16<bx<W-8 and p2-5<by<p2+30:
   vx=-(abs(vx)+0.15);vy+=(by-p2-13)/5
   hit=True;flash(W-11,int(p2),P2C)
  vy=max(-5.5,min(5.5,vy))
  vx=max(-7.0,min(7.0,vx))
  # Goal
  if bx<-5 or bx>W+5:
   if bx<-5:s2+=1
   else:s1+=1
   drawfield(s1,s2)
   p1=p2=H//2-15
   bx,by=float(W//2),float(H//2)
   vx=vy=0.0;paused=True
   if s1>=7 or s2>=7:
    F(0,0,W,H,BK)
    if s1>=7:
     D("YOU WIN!",105,70,(0,255,100),BK)
    else:
     D("CPU WINS",105,70,(255,80,60),BK)
    D(str(s1)+" - "+str(s2),130,100,WH,BK)
    D("OK = play again",80,145,(180,)*3,BK)
    D("Back = quit",105,170,(120,)*3,BK)
    while True:
     if K(17):return
     if okp():wup();break
     Z(0.05)
    s1=s2=0;drawfield(s1,s2)
   continue
  # Draw
  F(6,int(p1),5,30,P1C)
  F(W-11,int(p2),5,30,P2C)
  F(int(bx),int(by),5,5,BC)
  Z(0.018)

pong()

During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:

With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our cookies policy.