Jump to content
  • Advertisement
Sign in to follow this  
suika

help beginner in first game--strange behaviour

This topic is 3495 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
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!