• Advertisement
Sign in to follow this  

help beginner in first game--strange behaviour

This topic is 3319 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there, I'm new here and also I'm new to game programming.Since I was familiar with python I chose pygame as game engine.I was trying to do a tetris clone in the last couple of days and this code is the best I've come up with so far.But the strange behaviour is; it leaves unnecessary blocks here and there ,and I can't seem to figure out why.Can you have a look?
# -*- coding: utf-8 -*-
import pygame
import time,sys,random
pygame.init()
size=swidth,sheight=300,400
tposx,tposy,twidth,theight=backtile_rect=pygame.image.load("tbrick.png").get_rect()
print "backtile rect",backtile_rect,"twidth ",twidth,"theight",theight
background=[[None]*30 for y in range(40)]
dolu=[[0]*30 for y in range(40)]
screen=pygame.display.set_mode(size)
for y in range(40):   
    for x in range(30):
        background[y][x]=backtile_rect.move(twidth*x,theight*y)
        
arkaplan=pygame.image.load("ttrspng/arkaplan.png")
screen.blit(arkaplan,(0,0))
renkler={"mavi":"ttbrickmavi.png","yeşil":"ttbrickyesil.png","pembe":"ttbrickpembe.png",
		"sarı":"ttbricksari.png","turuncu":"ttbrickturuncu.png"}
random.seed()
r=random.Random()



class Nokta:
    def __init__(self,renk,krd):#krd=(x,y)
        self.x,self.y=krd #koordinatlar
        self.tileimage=pygame.image.load("ttrspng/"+renkler[renk])
    

    def geldikmi(self):
        if self.y==39 or dolu[self.y+1][self.x]: #son satırsa
            return True 
    
    def hareketEt(self,xyon=0):
        #print "kordinatlar" ,self.x,self.y
        if self.y<0: 
            self.y+=1    
        else:
            if self.x+xyon in range(30):
                self.x+=xyon #sağa sola hareket
            screen.blit(self.tileimage,background[self.y][self.x])
            self.y+=1
           
   

    def pozDeg(self,x,y):#şekli döndürürken lazım oluyor
        self.x+=x
        self.y+=y
    def renkGonder(self):
        return (self.tileimage,background[self.y][self.x])
        


class se:
    def __init__(self):
        self.x=r.randint(0,28)
        self.durum=0
        self.durumlar=["düz","yan"]
        renksec=r.choice(renkler.keys())
        self.n0=Nokta(renksec,(self.x+1,0))
        self.n1=Nokta(renksec,(self.x,-1))
        self.n2=Nokta(renksec,(self.x,-2))
        self.n3=Nokta(renksec,(self.x+1,-1))
        self.noktalar=[self.n0,self.n1,self.n2,self.n3]              
    def geldik(self):
        if True in [each.geldikmi() for each in self.noktalar]:
            return True #geldik
    def kiremitHareket(self,xyn):
        for each in self.noktalar:
            each.hareketEt(xyn)
    def Dur(self):
        for each in self.noktalar:
            dolu[each.y][each.x]=1 #doldur
            resim,alan=each.renkGonder()
            print "alan",alan
            arkaplan.blit(resim,alan) #noktayı arkaplanda sabitle
    def yap(self,xyn):
        if self.geldik():
            self.Dur()
            return False
        else:
            self.kiremitHareket(xyn)
            return True


    
    def cevir(self):
        if self.durum==0: #durumu değiştir
            self.durum=1
        else:
            self.durum=0
        if self.durumlar[self.durum]=="yan":
            self.noktalar[0].pozDeg(-1,1)
            self.noktalar[2].pozDeg(-1,-1)
            self.noktalar[3].pozDeg(0,-2)
    def noktablit(self):
        return [each.renkgonder() for each in self.noktalar]
            
            
    



def nextBrick():
    return kiremitsekli[r.choice(kiremitsekli.keys())]()
    

kiremitsekli={"şe":se}#"kare","çubuk","le","sağa yan le","sola yan le","şe":se}#,"sola şe","sağa şe","yukarı te"]

BEKLE=False
nb=nextBrick()
print "şe.x=%d " % nb.x
while 1:
    for event in pygame.event.get(): #events
        if event.type == pygame.QUIT :
            pygame.display.quit()
            sys.exit()
	if event.type == pygame.KEYDOWN:
		print event
		if event.key == 32:
			BEKLE=not BEKLE
    xyn=0 #keyeventle yon tesbit edilecek
    if not BEKLE:
	if nb.yap(xyn): #hareket etti
            pygame.display.update()
        else: #durdu
            nb=nextBrick()
            
            
            
    pygame.time.wait(100)
    screen.blit(arkaplan,(0,0)) #ekranı temizle
    pygame.display.update()
edit:I need to upload image files for the program to use, but I can't figure out how.

Share this post


Link to post
Share on other sites
Advertisement
Would it be possible for you to translate the variable/class names into English? For non syntax-related problems like this it will make tracking down the problem a bit easier

Share this post


Link to post
Share on other sites
Hey thanks for the reply, i would do that but i just managed to find out the problem.It was due to python lists' negative index feature.I'm giving negative y coordinates to block that should set out above other blocks.So, to fix the problem I just changed this function

def geldikmi(self): #check if a block hit the ground or another block
if self.y==39 or dolu[self.y+1][self.x]: #son satırsa
return True

to this:

def geldikmi(self):
if self.y>0:#if y is negative, don't count it
elif self.y==39 or dolu[self.y+1][self.x]: #son satırsa
return True

Share this post


Link to post
Share on other sites
A few suggestions. :) (The language is Turkish, yes? I don't really know any...)


# -*- coding: utf-8 -*-
import pygame
import time, sys, random
pygame.init()

load_image = pygame.image.load

size = swidth, sheight = 300, 400
tposx, tposy, twidth, theight = backtile_rect = load_image("tbrick.png").get_rect()

screen = pygame.display.set_mode(size)

# "dolu" is used as a set of boolean flags, so we should initialize it that way.
dolu = [[False] * 30 for y in range(40)]
# Instead of declaring a grid of blanks and then replacing the blanks, we
# can do the initialization directly:
background = [
[
backtile_rect.move(twidth * x, theight * y)
for x in range(30)
]
for y in range(40)
]

arkaplan = load_image("ttrspng/arkaplan.png")
screen.blit(arkaplan, (0, 0))

# If you don't mind losing the special characters,
# we can make use of the pattern between the block
# colour names and the file names...
renkler = dict(
(renk, load_image('ttrspng/ttbrick%s.png' % renk))
for renk in (
'mavi', 'yesil', 'pembe', 'sari', 'turuncu'
)
)

random.seed()
r = random.Random()


class Nokta:
# Don't use a short variable name and then explain it in
# comments. You don't really save any effort that way anyway.
def __init__(self, renk, koordinatlar):
self.x, self.y = koordinatlar
# Instead of loading the image for each block, we can store
# the images directly in 'renkler' and then just keep aliases
# to them...
self.tileimage = renkler[renk]


def geldikmi(self):
# Whenever you don't return anything explicitly, you
# return None implicitly. None happens to be "false"
# in an if-condition, but it's better not to rely on
# such tricks.
# Anyway, we can simplify this function (including the
# bug fix) with a little restructuring:
if self.y < 0: return False
if self.y == 39: return True
return dolu[self.y+1][self.x]


def hareketEt(self, xyon = 0):
# We add 1 to y no matter what, so just do that at the end...
if self.y >= 0:
if self.x + xyon in range(30): # This is a neat way to do the test :)
# I don't see that very often.
self.x += xyon # saga sola hareket

self.drawOn(screen) # see below
self.y += 1


def pozDeg(self, x, y): #sekli döndürürken lazim oluyor
self.x += x
self.y += y


# Instead of asking the block how to draw itself, ask it
# to make the draw call. Then you can reuse this function above...
# You can translate the name back if you like :)
def drawOn(self, what):
what.blit(self.tileimage, background[self.y][self.x])


class se:
def __init__(self):
self.x = r.randint(0, 28)
self.durum = False # Again this is used as a boolean
# ...and the "durumlar" names are not needed.
renksec = r.choice(renkler.keys())

# We don't need to store the pieces individually.
self.noktalar = [
Nokta(renksec, (self.x + 1, 0))
Nokta(renksec, (self.x, -1))
Nokta(renksec, (self.x, -2))
Nokta(renksec, (self.x + 1, -1))
]


def geldik(self):
# Again, instead of only returning True in the True
# case, and None in the False case, just return the
# test result directly. But there is also an easier
# way to write the test:
return any(each.geldikmi() for each in self.noktalar)


def kiremitHareket(self, xyn):
for each in self.noktalar:
each.hareketEt(xyn)


def Dur(self):
for each in self.noktalar:
dolu[each.y][each.x] = True
each.drawOn(arkaplan)


def yap(self, xyn):
# Just a small rearrangement. :)
geldik = self.geldik()
if geldik: self.Dur()
else: self.kiremitHareket(xyn)
return geldik


def cevir(self):
self.durum = not self.durum # nice and easy
# But are you sure that's what you want? Now
# the block will only rotate on every other call.
if self.durum:
# This doesn't look right to me at all...
# Also, will it work the second time?
# There's a standard way to do this by the way...
self.noktalar[0].pozDeg(-1, 1)
self.noktalar[2].pozDeg(-1, -1)
self.noktalar[3].pozDeg(0, -2)


#noktablit was not used anywhere.

# You don't really need to make a new class for each block shape.
# But we'll worry about that later.

# Don't pick a key and then take the corresponding value;
# what you want is any of the values, so just take that...
def nextBrick():
return r.choice(kiremitsekli.values())()


kiremitsekli = {
"se": se,
} # "kare", "çubuk", "le", "saga yan le", "sola yan le", "se":se }#,"sola se","saga se","yukari te"]


BEKLE = False
nb = nextBrick()
while True: # Again, use real booleans where you mean them.
# I guess you didn't implement this part fully yet. :)
xyn = 0 # keyeventle yon tesbit edilecek
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.display.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == 32:
BEKLE = not BEKLE

if not BEKLE:
if nb.yap(xyn): # hareket etti
pygame.display.update()
else: # durdu
nb = nextBrick()

pygame.time.wait(100)
screen.blit(arkaplan, (0, 0)) #ekrani temizle
pygame.display.update()

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
A few suggestions. :) (The language is Turkish, yes? I don't really know any...)

*** Source Snippet Removed ***


Thanks for the suggestions, I will look into them.(yes, Turkish:)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement