Need help fixing Time and Score issues - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Game Development (https://python-forum.io/forum-11.html) +--- Thread: Need help fixing Time and Score issues (/thread-6335.html) |
Need help fixing Time and Score issues - Kingrocket10 - Nov-16-2017 Hello I would like some help on my game. My Score and Time limit do not work at all so I would like help fixing that. The digits underneath the Time limit and score spots don't even show up and I can't figure out why. Also tons of blue numbers show up on the shell side, is this normal? It looks like its processing the Ids. This is the block that gives the points when touched: (yblock) & at times (ybloc). Thank you. My Code: import os from tkinter import * from random import randint from time import sleep, time from math import sqrt HEIGHT = 1000 WIDTH = 900 window = Tk() window.title('Strange Game') c = Canvas(window, width=WIDTH, height=HEIGHT, bg='black') c.pack() block_id = c.create_rectangle(0, 0, 40, 40, outline='red', fill='red') BLOCK_R = 15 MID_X = WIDTH / 2 MID_Y = HEIGHT / 2 c.move(block_id, MID_X, MID_Y) BLOCK_SPD = 15 yblock_id = list() yblock_r = list() yblock_speed = list() MIN_YBLOCK_R = 5 MAX_YBLOCK_R = 10 MAX_YBLOCK_SPD = 2 GAP = 100 YBLOCK_CHANCE = 100 TIME_LIMIT = 30 BONUS_SCORE = 1000 score = 0 bonus = 0 end = time() + TIME_LIMIT def move_block(event): if event.keysym == 'Up': c.move(block_id, 0, -BLOCK_SPD) elif event.keysym == 'Down': c.move(block_id, 0, BLOCK_SPD) elif event.keysym == 'Left': c.move(block_id, -BLOCK_SPD, 0) elif event.keysym == 'Right': c.move(block_id, BLOCK_SPD, 0) def create_ybloc(): x = randint(0, WIDTH) y = randint(0, 0) r = randint(MIN_YBLOCK_R, MAX_YBLOCK_R) id1 = c.create_rectangle(x - r, y - r, x + r, y + r, outline='yellow') yblock_id.append(id1) yblock_r.append(r) yblock_speed.append(randint(1, MAX_YBLOCK_SPD)) def move_yblocs(): for i in range(len(yblock_id)): c.move(yblock_id[i], 0, yblock_speed[i]) def get_coords(id_num): pos = c.coords(id_num) x = (pos[0] + pos[2])/2 y = (pos[1] + pos[3])/2 return x, y def del_ybloc(i): del yblock_r[i] del yblock_speed[i] c.delete(yblock_id[i]) del yblock_id[i] def clean_up_yblocks(): for i in range(len(yblock_id)-1, -1, -1): x, y = get_coords(yblock_id[i]) if x < -GAP: del_ybloc(i) def distance(id1, id2): x1, y1 = get_coords(id1) x2, y2 = get_coords(id2) return sqrt((x2 - x1)**2 + (y2 - y1)**2) def show_score(score): c.itemconfig(score_text, text=str(score)) def show_time(time_left): c.itemconfig(time_text, text=str(time_left)) def collision(): points = 0 for yblock in range(len(yblock_id)-1, -1, -1): if distance(block_id, yblock_id[yblock]) < (BLOCK_R + yblock_r[yblock]): points += (yblock_r[yblock] + yblock_speed[yblock]) del_ybloc(yblock) return points c.bind_all('<Key>', move_block) c.create_text(50, 30, text='TIME', fill='white' ) c.create_text(150, 30, text='SCORE', fill='white' ) time_text = c.create_text(50, 50, fill='white' ) score_text = c.create_text(150, 50, fill='white' ) #MAIN GAME LOOP while time() < end: if randint(1, YBLOCK_CHANCE) == 1: create_ybloc() move_yblocs() clean_up_yblocks score += collision() if (int(score / BONUS_SCORE)) > bonus: bonus += 1 end += TIME_LIMIT show_score(score) show_time(int(end - time())) print(score) window.update() sleep(0.01) c.create_text(MID_X, MID_Y, \ text='GAME OVER', fill='white', font=('Helvetica',30)) c.create_text(MID_X, MID_Y + 30, \ text='Score: '+ str(score), fill='white') c.create_text(MID_X, MID_Y + 45, \ text='Bonus time: '+ str(bonus*TIME_LIMIT), fill='white') RE: Need help fixing Time and Score issues - Windspar - Nov-16-2017 1. Code need better organize. Very hard to follow. 2. score has to be 1000 or better to show time or score. Because of this line. if (int(score / BONUS_SCORE) > bonus:suggestion: take them out of if block. 3. errors that haven't show up yet. score_text and time_text must be above function. To make more readable 1. put all const together 2. make a function for main game. this is where changable variables go. 3. use better variables names. Like c should be canvas. something readable. just a suggestion like score_text to me should be score_id. 4. from tkinter import *It just bad to flood namespace. No matter what tutorials says. use something like this instead import tkinter as tk5. Just because this bothers me. in create_ybloc() remove the y from everywhere. Just a waste of cpu cycles. RE: Need help fixing Time and Score issues - Windspar - Nov-17-2017 Here my example of your code. Still don't like how keypress works. import tkinter as tk from random import randint WIDTH = 1000 HEIGHT = 700 MID_X = WIDTH / 2 MID_Y = HEIGHT / 2 class YellowBlock: MAX_SPEED = 2 def __init__(self, canvas): self.value = randint(5, 10) x = randint(self.value + 1, WIDTH - self.value) self.id = canvas.create_rectangle(x - self.value, -self.value, x + self.value, self.value, outline='yellow') self.speed = randint(1, YellowBlock.MAX_SPEED) def move(self, canvas): canvas.move(self.id, 0, self.speed) class Game: def __init__(self): self.score = 0 self.bonus = 0 self.time = 31 self.yblocks = {} # tk stuff self.window = tk.Tk() self.canvas = tk.Canvas(self.window, width=WIDTH, height=HEIGHT, bg='black') self.canvas.pack() self.canvas.create_text(50, 30, text='TIME', fill='white' ) self.canvas.create_text(150, 30, text='SCORE', fill='white' ) self.time_id = self.canvas.create_text(50, 50, fill='white' ) self.score_id = self.canvas.create_text(150, 50, fill='white' ) self.block_id = self.canvas.create_rectangle(0, 0, 40, 40, fill='red') self.canvas.move(self.block_id, MID_X, MID_Y) self.speed = 15 self.window.bind_all('<Key>', self.keys_press) # game over self.game_over_id = None self.game_score_id = None # start time loops self.loop_id = None self.time_loop_id = None self.loop() self.time_loop() def new_game(self): self.score = 0 self.bonus = 0 self.time = 31 self.canvas.itemconfig(self.score_id, text='0') # recenter player x, y , w, h = self.canvas.coords(self.block_id) self.canvas.move(self.block_id, MID_X - (x + w) / 2, MID_Y - (y + h) / 2) # remove left over blocks for key in self.yblocks.keys(): self.canvas.delete(key) self.yblocks = {} # reset game over if self.game_over_id: self.canvas.delete(self.game_over_id) if self.game_score_id: self.canvas.delete(self.game_score_id) self.game_over_id = None self.game_score_id = None # stop timers if self.time_loop_id: self.window.after_cancel(self.time_loop_id) if self.loop_id: self.window.after_cancel(self.loop_id) # start time loops self.loop_id = None self.time_loop_id = None self.loop() self.time_loop() def keys_press(self, event): if event.keysym == 'Up': self.canvas.move(self.block_id, 0, -self.speed) elif event.keysym == 'Down': self.canvas.move(self.block_id, 0, self.speed) elif event.keysym == 'Left': self.canvas.move(self.block_id, -self.speed, 0) elif event.keysym == 'Right': self.canvas.move(self.block_id, self.speed, 0) elif event.keysym == 'Escape': self.window.destroy() elif event.keysym == 'n': self.new_game() def collide(self, box): x, y, w, h = self.canvas.bbox(self.block_id) return ( (((x > box[0]) and (x < box[2])) or ((box[0] > x) and (box[0] < w))) and (((y > box[1]) and (y < box[3])) or ((box[1] > y) and (box[1] < h)))) def loop(self): if self.time < 0: if self.time_loop_id: self.window.after_cancel(self.time_loop_id) if self.loop_id: self.window.after_cancel(self.loop_id) self.game_over_id = self.canvas.create_text(MID_X, MID_Y, text='GAME OVER', fill='white', font=('Helvetica',30)) self.game_score_id = self.canvas.create_text(MID_X, MID_Y + 30, text='Score: '+ str(self.score), fill='white') # return for it can't assign another cycle return if randint(1, 50) == 1 or len(self.yblocks) < 2: yellow_block = YellowBlock(self.canvas) self.yblocks[yellow_block.id] = yellow_block blocks_remove = [] for item_id, block in self.yblocks.items(): x, y, w, h = self.canvas.bbox(item_id) # move block block.move(self.canvas) # object fell offscreen if y > HEIGHT + 1: blocks_remove.append(item_id) # collision else: if self.collide((x,y,w,h)): blocks_remove.append(item_id) self.score += block.value self.canvas.itemconfig(self.score_id, text=str(self.score)) for key in blocks_remove: self.canvas.delete(key) del self.yblocks[key] # roughly 30 frames per second self.loop_id = self.window.after(int(1000/30), self.loop) def time_loop(self): self.time -= 1 self.canvas.itemconfig(self.time_id, text=str(self.time)) self.time_loop_id = self.window.after(1000, self.time_loop) def main(): game = Game() game.window.mainloop() main() RE: Need help fixing Time and Score issues - Windspar - Nov-18-2017 I perfer classes over function but here one without classes. Here another example using function with some improvements and better tkinter code. import tkinter as tk from random import randint, choice WIDTH = 1000 HEIGHT = 700 MID_X = WIDTH / 2 MID_Y = HEIGHT / 2 CHOICE = [1, 1, 1, 1] + [2 for n in range(150)] + [3, 4] # globals stop_game = 0 time_end = False block_id = None bonus_time = 0 # countdown def time_loop(canvas, time_id, time): global time_end, bonus_time if bonus_time: time += bonus_time bonus_time = 0 time -= 1 if stop_game: loop_stop(canvas) return if time < 0: time_end = True loop_stop(canvas) return canvas.itemconfig(time_id, text=str(time)) # 1000 milliseconds = 1 seconds canvas.after(1000, time_loop, canvas, time_id, time) def collide(canvas, box): x, y, w, h = canvas.bbox(block_id) return ( (((x > box[0]) and (x < box[2])) or ((box[0] > x) and (box[0] < w))) and (((y > box[1]) and (y < box[3])) or ((box[1] > y) and (box[1] < h)))) def game_loop(canvas, score_id, score, yblocks): global bonus_time if time_end: canvas.create_text(MID_X, MID_Y, text='GAME OVER', fill='white', font=('Helvetica',30)) canvas.create_text(MID_X, MID_Y + 30, text='Score: '+ str(score), fill='white') # stop game_loop timer loop_stop(canvas) return if stop_game: loop_stop(canvas) return add_block = choice(CHOICE) if add_block != 2 or len(yblocks) < 4: value = randint(5, 10) x = randint(value, WIDTH - value) # pick a color from list. color = [None, 'yellow', 'yellow', 'green', 'orange'][add_block] square_id = canvas.create_rectangle(x - value, -value, x + value, value, outline=color) if add_block == 4: yblocks[square_id] = (value * 4, 7, 4) elif add_block == 3: yblocks[square_id] = (value + 1, 4, 3) else: yblocks[square_id] = (value, randint(1, 2), 1) # value of block , speed, block_choice # remove block, collision , move block remove_block = [] for item_id, values in yblocks.items(): box = canvas.bbox(item_id) # move yellow block down canvas.move(item_id, 0, values[1]) # yellow block off screen if box[1] > HEIGHT: remove_block.append(item_id) # collision else: if(collide(canvas, box)): remove_block.append(item_id) score += values[0] if values[2] == 3: bonus_time += 2 canvas.itemconfig(score_id, text=str(score)) # remove yellow blocks for key in remove_block: canvas.delete(key) del yblocks[key] canvas.after(int(1000/30), game_loop, canvas, score_id, score, yblocks) # stopping all loops def loop_stop(canvas): global stop_game stop_game += 1 if stop_game == 3: new_game(canvas) def new_game(canvas): global block_id, time_end, stop_game stop_game = 0 time_end = False # remove all items from canvas canvas.delete('all') canvas.create_text(50, 30, text='TIME', fill='white' ) canvas.create_text(150, 30, text='SCORE', fill='white' ) time_id = canvas.create_text(50, 50, fill='white' ) score_id = canvas.create_text(150, 50, fill='white', text='0') block_id = canvas.create_rectangle(0, 0, 40, 40, fill='red') canvas.move(block_id, MID_X, MID_Y) # start timers game_loop(canvas, score_id, 0, {}) time_loop(canvas, time_id, 31) def main(): window = tk.Tk() canvas = tk.Canvas(window, width=WIDTH, height=HEIGHT, bg='black') canvas.pack() new_game(canvas) def keys_press(event): speed = 15 if event.keysym == 'Up': canvas.move(block_id, 0, -speed) elif event.keysym == 'Down': canvas.move(block_id, 0, speed) elif event.keysym == 'Left': canvas.move(block_id, -speed, 0) elif event.keysym == 'Right': canvas.move(block_id, speed, 0) elif event.keysym == 'Escape': window.destroy() elif event.keysym == 'n': loop_stop(canvas) window.bind_all('<Key>', keys_press) window.mainloop() if __name__ == '__main__': main() RE: Need help fixing Time and Score issues - Windspar - Nov-18-2017 Okay figure out keypress work smoothly. Enjoy. import tkinter as tk from random import randint, choice, shuffle WIDTH = 1000 HEIGHT = 700 MID_X = WIDTH / 2 MID_Y = HEIGHT / 2 class FallingBlock: CHOICE = [0,0,0,0,2,3] + [1 for n in range(170)] def __init__(self, canvas, choice_id): self.value = randint(5, 10) x = randint(self.value + 1, WIDTH - self.value) self.color_id = choice_id color = ['yellow', 'yellow', 'green', 'orange'][self.color_id] self.id = canvas.create_rectangle(x - self.value, -self.value, x + self.value, self.value, outline=color) if self.color_id == 3: self.speed = 8 self.value *= 5 elif self.color_id == 2: self.speed = 4 self.value += 2 else: self.speed = randint(1, 2) def move(self, canvas): canvas.move(self.id, 0, self.speed) class Game: def __init__(self): self.window = tk.Tk() self.canvas = tk.Canvas(self.window, width=WIDTH, height=HEIGHT, bg='black') self.canvas.pack() self.window.bind_all('<KeyPress>', self.keys_press) self.window.bind_all('<KeyRelease>', self.keys_release) self.speed = 10 self.loop_id = None self.time_loop_id = None self.new_game() def new_game(self): shuffle(FallingBlock.CHOICE) self.falling_blocks = {} self.keys = {} self.score = 0 self.bonus = 0 self.time = 31 self.canvas.delete('all') self.canvas.create_text(50, 30, text='TIME', fill='white' ) self.canvas.create_text(150, 30, text='SCORE', fill='white' ) self.time_id = self.canvas.create_text(50, 50, fill='white' ) self.score_id = self.canvas.create_text(150, 50, fill='white', text='0') self.block_id = self.canvas.create_rectangle(0, 0, 40, 40, fill='red') self.canvas.move(self.block_id, MID_X, MID_Y) # stop timers if self.time_loop_id: self.window.after_cancel(self.time_loop_id) if self.loop_id: self.window.after_cancel(self.loop_id) # start time loops self.loop_id = None self.time_loop_id = None self.loop() self.time_loop() def keys_press(self, event): if event.keysym in ['Up', 'Down', 'Left', 'Right']: self.keys[event.keysym] = True elif event.keysym == 'Escape': self.window.destroy() elif event.keysym == 'n': self.new_game() def keys_release(self, event): if event.keysym in ['Up', 'Down', 'Left', 'Right']: self.keys[event.keysym] = False def collide(self, box): x, y, w, h = self.canvas.bbox(self.block_id) return ( (((x > box[0]) and (x < box[2])) or ((box[0] > x) and (box[0] < w))) and (((y > box[1]) and (y < box[3])) or ((box[1] > y) and (box[1] < h)))) def loop(self): if self.time < 0: self.canvas.create_text(MID_X, MID_Y, text='GAME OVER', fill='white', font=('Helvetica',30)) self.canvas.create_text(MID_X, MID_Y + 30, text='Score: '+ str(self.score), fill='white') # return for it can't assign another cycle return # Moving Player if self.keys.get('Left', False): self.canvas.move(self.block_id, -self.speed, 0) if self.keys.get('Right', False): self.canvas.move(self.block_id, self.speed, 0) if self.keys.get('Up', False): self.canvas.move(self.block_id, 0, -self.speed) if self.keys.get('Down', False): self.canvas.move(self.block_id, 0, self.speed) falling_id = choice(FallingBlock.CHOICE) if falling_id != 1 or len(self.falling_blocks) < 4: fall_block = FallingBlock(self.canvas, falling_id) self.falling_blocks[fall_block.id] = fall_block blocks_remove = [] for item_id, block in self.falling_blocks.items(): box = self.canvas.bbox(item_id) # move block block.move(self.canvas) # object fell offscreen if box[1] > HEIGHT + 1: blocks_remove.append(item_id) # collision else: if self.collide(box): if block.color_id == 2: self.time += 2 blocks_remove.append(item_id) self.score += block.value self.canvas.itemconfig(self.score_id, text=str(self.score)) for key in blocks_remove: self.canvas.delete(key) del self.falling_blocks[key] # roughly 30 frames per second self.loop_id = self.window.after(int(1000/30), self.loop) def time_loop(self): self.time -= 1 if self.time < 0: return self.canvas.itemconfig(self.time_id, text=str(self.time)) self.time_loop_id = self.window.after(1000, self.time_loop) def main(): game = Game() game.window.mainloop() main() RE: Need help fixing Time and Score issues - hammza - Dec-07-2017 Perfect |