My main program for a Bloxorz-Type program is working fine. Only issue I have is having to implement a system where the game shows a message on the screen if the block falls off the map, and a gameFinished message on the screen when the block hits the hole vertically. I'm thinking the way it would work is to match the coordinates of the hole and if the coordinates of the hole match the square-bases of the block, it will show a message.
My first real issue is being able to display a startMenu message, where it will display "Press S to Start" and "press Q to quit". I know how to use the scene.kb.getkey(), the only problem is displaying the text on the screen, which i will implement into my main while True loop. Here is my code:
from __future__ import division, print_function
from visual import *
import math, sys
from visual.graph import *
from sys import exit
"""Necessary Python Libraries"""
# top, left, bottom, right, front, back
tlbrfb = ( 2.0, -0.5, 0.0, 0.5, 0.5, -0.5 ) #the area that the block covers (dimensions)
Top = 0
Left = 1
Bottom = 2
Right = 3
Front = 4
Back = 5
"""Modules defining the Movement of the Block"""
def moveRight():
global tlbrfb
for r in range(0, 9):
rate(30)
block.rotate( angle = pi/18, axis = vector( 0, 0, -1), origin = vector(tlbrfb[Right], 0, 0) ) #pi/18 = 10degrees,
tlbrfb = (tlbrfb[Right]-tlbrfb[Left], tlbrfb[Right], 0, tlbrfb[Right]+tlbrfb[Top], tlbrfb[Front], tlbrfb[Back]) #update block's state of stance
def moveDown():
global tlbrfb
for r in range(0, 9):
rate(30)
block.rotate( angle = pi/18, axis = vector( +1, 0, 0), origin = vector(0, 0, tlbrfb[Front]) )
tlbrfb = (tlbrfb[Front]-tlbrfb[Back], tlbrfb[Left], 0, tlbrfb[Right], tlbrfb[Front]+tlbrfb[Top], tlbrfb[Front])
def moveLeft():
global tlbrfb
for r in range(0, 9):
rate(30)
block.rotate( angle = pi/18, axis = vector( 0, 0, +1), origin = vector(tlbrfb[Left], 0, 0) )
tlbrfb = (tlbrfb[Right]-tlbrfb[Left], tlbrfb[Left]-tlbrfb[Top], 0, tlbrfb[Left], tlbrfb[Front], tlbrfb[Back] )
def moveUp():
global tlbrfb
for r in range(0, 9):
rate(30)
block.rotate( angle = pi/18, axis = vector( -1, 0, 0), origin = vector(0, 0, tlbrfb[Back]) )
tlbrfb = (tlbrfb[Front]-tlbrfb[Back], tlbrfb[Left], 0, tlbrfb[Right], tlbrfb[Back], tlbrfb[Back]-tlbrfb[Top])
level1 = [ #array on the tile placement
[1,1,1,0,0,0,0,0,0,0],
[1,1,1,1,1,0,0,0,0,0],
[1,1,1,1,1,1,1,1,1,0],
[0,0,0,0,0,1,1,0,1,1],
[0,0,0,0,0,0,1,1,1,0]
]
def draw_level(array):
for y in range(0, len(array)):
for x in range(0, len(array[y])):
if array[y][x] == 1:
box( pos=vector(x, -0.1, y), length=0.9, width = 0.9, height = 0.2, color = vector(0.9, 0.8, 0.8))
block = box( pos=vector(0,1,0), length = 1, width = 1, height = 2, color = vector(0.9, 0.9, 0.5))
def handle_events():
key = scene.kb.getkey()
if key =="up":
moveUp()
elif key =="down":
moveDown()
elif key == "left":
moveLeft()
elif key == "right":
moveRight()
elif key == "q":
quit()
elif key == "escape":
quit()
def mainGameLoop():
while True:
scene.center = vector(4.5, 0, 2)
scene.forward = scene.center - vector(2, 6, 10)
scene.background = vector(0.57, 0.2, 0.2)
draw_level(level1) #draw mapout
handle_events()
while True:
mainGameLoop()
handle_events()
print(block.pos)
Related
I have this snippet from part of a code I'm working on with pyqtgraph ROI. I have also set boundaries in which the ROI cannot cross on all sides. When I move either of the vertical scale handles, it gives the ROI an opportunity to move left-right if click inside of it. Is there a way to prevent this from happening? I only want it to move up-down. This is kind of like setting another bound within the original bound to the ROI depending on the current X start position and X stop position.
I tried modifying the self.maxBound variable in the ROI class using signals but it became messy, and the ROI kept ignoring the right bound.
Any help will be greatly appriciated
from PyQt5.QtWidgets import (
QApplication,
QMainWindow,
QGridLayout,
QWidget)
import pyqtgraph as pg
import sys
import numpy as np
from PyQt5.QtCore import QRectF, QRect
class TestROI(QMainWindow):
imageWidth = 1000
imageHardLimitTop = 1048
imageHardLimitBottom = 2047
shallowestPixel = 1400
deepestPixel = 1699
ROITopBottomMargin = 20
shaderDarkness = 185
shaderColor = (0, 0, 50, shaderDarkness)
imageHardLimitDepth = imageHardLimitBottom - imageHardLimitTop + 1
def __init__(self):
super(TestROI, self).__init__()
self.mainWidget = QWidget()
self.imagePlotCanvas = pg.GraphicsLayoutWidget()
self.graphGridLayout = QGridLayout(self.mainWidget)
self.graphGridLayout.addWidget(self.imagePlotCanvas)
self.setCentralWidget(self.mainWidget)
self.showMaximized()
# Place for 2D images:
self.plotArea = self.imagePlotCanvas.addPlot()
self.plotArea.setRange(
QRect(0, self.imageHardLimitTop, self.imageWidth, self.imageHardLimitDepth))
self.plotArea.setLimits(xMin=-1000, xMax=2000)
self.plotArea.setAspectLocked(True)
self.plotArea.invertY(b=True)
self.plotArea.showGrid(x=True, y=True, alpha=1.0)
self.plotArea.showButtons()
self.twoDImageROI = pg.ROI(pos=[0, self.shallowestPixel],
size=[
self.imageWidth, self.deepestPixel - self.shallowestPixel + 1],
removable=False,
maxBounds=QRectF(-1, self.imageHardLimitTop-1,
self.imageWidth + 2, self.imageHardLimitDepth+1),
scaleSnap=False, translateSnap=False)
self.twoDImageROI.setZValue(20)
self.shadedTopRegion = pg.LinearRegionItem(
[self.imageHardLimitTop, self.shallowestPixel], orientation=pg.LinearRegionItem.Horizontal, movable=False)
self.shadedTopRegion.setBrush(color=self.shaderColor)
self.shadedTopRegion.setZValue(10)
self.plotArea.addItem(self.shadedTopRegion)
self.shadedBottomRegion = pg.LinearRegionItem(
[self.deepestPixel + 1, self.imageHardLimitBottom+1], orientation=pg.LinearRegionItem.Horizontal, movable=False)
self.shadedBottomRegion.setBrush(color=self.shaderColor)
self.shadedBottomRegion.setZValue(10)
self.plotArea.addItem(self.shadedBottomRegion)
# self.twoDImageROI.setAcceptedMouseButtons(Qt.LeftButton)
self.twoDImageROI.sigRegionChanged.connect(self.imageROIChanged)
# Shaded Region on the left and right to cover up the above two vertical lines when out of image bound.
self.shadedLeftRegion = pg.LinearRegionItem(
[-1000, 0], orientation=pg.LinearRegionItem.Vertical, movable=False)
self.shadedLeftRegion.setBrush(color=(0, 0, 0))
self.shadedLeftRegion.setZValue(20)
self.plotArea.addItem(self.shadedLeftRegion)
self.shadedRightRegion = pg.LinearRegionItem(
[1000, 2000], orientation=pg.LinearRegionItem.Vertical, movable=False)
self.shadedRightRegion.setBrush(color=(0, 0, 0))
self.shadedRightRegion.setZValue(20)
self.plotArea.addItem(self.shadedRightRegion)
self.twoDImageROI.addScaleHandle([0.5, 0.0], [0.5, 1.0], index=0)
self.twoDImageROI.addScaleHandle([0.5, 1.0], [0.5, 0.0], index=1)
self.twoDImageROI.addScaleHandle([1.0, 0.5], [0.5, 0.5])
self.twoDImageROI.addScaleHandle([0.0, 0.5], [0.5, 0.5])
self.twoDOCMImage = pg.ImageItem(border='c')
self.twoDOCMImage.setParentItem(self.plotArea)
self.plotArea.addItem(self.twoDOCMImage)
self.plotArea.addItem(self.twoDImageROI)
zeroImage = np.zeros(self.imageWidth * self.imageHardLimitDepth)\
.reshape((self.imageWidth, self.imageHardLimitDepth))
self.twoDOCMImage.setImage(zeroImage)
startingRect = QRect(0, self.imageHardLimitTop,
self.imageWidth, self.imageHardLimitDepth)
self.twoDOCMImage.setRect(startingRect)
def imageROIChanged(self):
x, top = self.twoDImageROI.pos()
top = int(round(top, 0))
w, h = self.twoDImageROI.size()
h = int(round(h, 0))
bot = top + h - 1
self.shallowestPixel = top
self.deepestPixel = bot
self.updateLinearRegion()
def updateLinearRegion(self):
x, top = self.twoDImageROI.pos()
top = int(round(top, 0))
w, h = self.twoDImageROI.size()
h = int(round(h, 0))
bot = top + h - 1
self.shadedTopRegion.setRegion([self.imageHardLimitTop, top])
self.shadedBottomRegion.setRegion([bot, self.imageHardLimitBottom+1])
if __name__ == '__main__':
app = QApplication(sys.argv)
main_window = TestROI()
main_window.show()
sys.exit(app.exec_())
I believe that issue You are talking about is this 1px wiggle from left to right when moving ROI up and down. This effect is due to the translation of real ROI position to plot X, Y values. There will always be rounding and thus ROI will always wiggle a bit left and right.
To prevent this, You can manually set constant x position of Your ROI. For that, You have to override setPos of ROI class.
Here is example ROI class, that You can use:
class ConstantXROI(ROI):
constant_x = 0
def setPos(self, pos, y=None, update=True, finish=True):
pos.setX(self.constant_x)
super().setPos(pos, y=y, update=update, finish=finish)
Then in Your code, just use:
self.twoDImageROI = ConstantXROI(...)
If I pick a world point from a image, How can I convert the world coordinate to image index?
import vtk
import numpy as np
from vtk.util.numpy_support import numpy_to_vtk
def numpyToVTK(data, multi_component=False, type='float'):
if type == 'float':
data_type = vtk.VTK_FLOAT
elif type == 'char':
data_type = vtk.VTK_UNSIGNED_CHAR
else:
raise RuntimeError('unknown type')
if multi_component == False:
if len(data.shape) == 2:
data = data[:, :, np.newaxis]
flat_data_array = data.transpose(2,1,0).flatten()
vtk_data = numpy_to_vtk(num_array=flat_data_array, deep=True, array_type=data_type)
shape = data.shape
else:
assert len(data.shape) == 3, 'only test for 2D RGB'
flat_data_array = data.transpose(1, 0, 2)
flat_data_array = np.reshape(flat_data_array, newshape=[-1, data.shape[2]])
vtk_data = numpy_to_vtk(num_array=flat_data_array, deep=True, array_type=data_type)
shape = [data.shape[0], data.shape[1], 1]
img = vtk.vtkImageData()
img.GetPointData().SetScalars(vtk_data)
img.SetDimensions(shape[0], shape[1], shape[2])
return img
global sphereActor, textActor
sphereActor = None
textActor = None
def mouseMoveEvent(iren, event):
x, y = iren.GetEventPosition()
picker = vtk.vtkWorldPointPicker()
picker.Pick(x, y, 0, render)
worldPoint = picker.GetPickPosition()
##############################################
## convert world point to image index
##############################################
sphere = vtk.vtkSphereSource()
sphere.SetCenter(worldPoint[0], worldPoint[1], worldPoint[2])
sphere.SetRadius(2)
sphere.Update()
sphereMapper = vtk.vtkPolyDataMapper()
sphereMapper.SetInputData(sphere.GetOutput())
global sphereActor, textActor
if sphereActor != None:
render.RemoveActor(sphereActor)
sphereActor = vtk.vtkActor()
sphereActor.SetMapper(sphereMapper)
sphereActor.GetProperty().SetColor(255, 0, 0)
render.AddActor(sphereActor)
render.Render()
if textActor != None:
render.RemoveActor(textActor)
textActor = vtk.vtkTextActor()
textActor.SetInput('world coordinate: (%.2f, %.2f, %.2f)'%(worldPoint[0], worldPoint[1], worldPoint[2]))
textActor.GetTextProperty().SetColor(1, 0, 0)
textActor.GetTextProperty().SetFontSize(15)
render.AddActor(textActor)
img = np.zeros(shape=[128, 128])
for i in range(128):
for j in range(128):
img[i, j] = i+j
vtkImg = numpyToVTK(img)
imgActor = vtk.vtkImageActor()
imgActor.SetInputData(vtkImg)
render = vtk.vtkRenderer()
render.AddActor(imgActor)
# render.Render()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(render)
renWin.Render()
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
iren.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
iren.Initialize()
iren.AddObserver('MouseMoveEvent', mouseMoveEvent)
iren.Start()
In the above code, if I don't rotate the image, the world point is (x, y, 0):
And it is agree with what I know. For the world point (x, y, z) and the image index (i, j, k), the conversion should be:
worldPoint (x,y,z) = i*spacingX*directionX + j*spacingY*directionY + k*spacingZ*directionZ + originPoint
In the above code, the image is converted from numpy, thus:
directionX = [1, 0, 0]
directionY = [0, 1, 0]
directionZ = [0, 0, 1]
originPoint=[0, 0, 0]
spacingX=1
spacingY=1
spacingZ=1
In this way, x=i, y=j, z=k. Since this image is a 2D image, the k should be 0 and 'z' should also be 0.
Then, I rotate the image, z is not 0. Like the following picture.
I don't know why z is -0.24.
It means the following conversion is wrong. And how can I obtain the image index by the world point?
worldPoint (x,y,z) = i*spacingX*directionX + j*spacingY*directionY + k*spacingZ*directionZ + originPoint
Any suggestion is appreciated!
vtkImageData has the method TransformPhysicalPointToContinuousIndex for going from world space to image space and TransformIndexToPhysicalPoint to go the other way.
I don't think the computation you're doing is right, since direction is 3x3 rotation matrix.
This question already has answers here:
Pygame - Mouse clicks not getting detected
(2 answers)
Closed 2 years ago.
I am currently working on a CS50 project studying the AI required for tic-tac-toe. however I can't get the runner.py file to run, as I get the following error:
Traceback (most recent call last): File
"/Users/newtracksuit/Downloads/tictactoe/runner.py", line 57, in
click, _, _ = pygame.mouse.get_pressed() ValueError: too many values to unpack (expected 3)
here is the full code provided, I have yet to write any actual functionality to the tic-tac-toe program, Just need to understand why this is not working yet
import pygame
import sys
import time
import tictactoe as ttt
pygame.init()
size = width, height = 600, 400
# Colors
black = (0, 0, 0)
white = (255, 255, 255)
screen = pygame.display.set_mode(size)
mediumFont = pygame.font.Font("OpenSans-Regular.ttf", 28)
largeFont = pygame.font.Font("OpenSans-Regular.ttf", 40)
moveFont = pygame.font.Font("OpenSans-Regular.ttf", 60)
user = None
board = ttt.initial_state()
ai_turn = False
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill(black)
# Let user choose a player.
if user is None:
# Draw title
title = largeFont.render("Play Tic-Tac-Toe", True, white)
titleRect = title.get_rect()
titleRect.center = ((width / 2), 50)
screen.blit(title, titleRect)
# Draw buttons
playXButton = pygame.Rect((width / 8), (height / 2), width / 4, 50)
playX = mediumFont.render("Play as X", True, black)
playXRect = playX.get_rect()
playXRect.center = playXButton.center
pygame.draw.rect(screen, white, playXButton)
screen.blit(playX, playXRect)
playOButton = pygame.Rect(5 * (width / 8), (height / 2), width / 4, 50)
playO = mediumFont.render("Play as O", True, black)
playORect = playO.get_rect()
playORect.center = playOButton.center
pygame.draw.rect(screen, white, playOButton)
screen.blit(playO, playORect)
# Check if button is clicked
click, _, _ = pygame.mouse.get_pressed()
if click == 1:
mouse = pygame.mouse.get_pos()
if playXButton.collidepoint(mouse):
time.sleep(0.2)
user = ttt.X
elif playOButton.collidepoint(mouse):
time.sleep(0.2)
user = ttt.O
else:
# Draw game board
tile_size = 80
tile_origin = (width / 2 - (1.5 * tile_size),
height / 2 - (1.5 * tile_size))
tiles = []
for i in range(3):
row = []
for j in range(3):
rect = pygame.Rect(
tile_origin[0] + j * tile_size,
tile_origin[1] + i * tile_size,
tile_size, tile_size
)
pygame.draw.rect(screen, white, rect, 3)
if board[i][j] != ttt.EMPTY:
move = moveFont.render(board[i][j], True, white)
moveRect = move.get_rect()
moveRect.center = rect.center
screen.blit(move, moveRect)
row.append(rect)
tiles.append(row)
game_over = ttt.terminal(board)
player = ttt.player(board)
# Show title
if game_over:
winner = ttt.winner(board)
if winner is None:
title = f"Game Over: Tie."
else:
title = f"Game Over: {winner} wins."
elif user == player:
title = f"Play as {user}"
else:
title = f"Computer thinking..."
title = largeFont.render(title, True, white)
titleRect = title.get_rect()
titleRect.center = ((width / 2), 30)
screen.blit(title, titleRect)
# Check for AI move
if user != player and not game_over:
if ai_turn:
time.sleep(0.5)
move = ttt.minimax(board)
board = ttt.result(board, move)
ai_turn = False
else:
ai_turn = True
# Check for a user move
click, _, _ = pygame.mouse.get_pressed()
if click == 1 and user == player and not game_over:
mouse = pygame.mouse.get_pos()
for i in range(3):
for j in range(3):
if (board[i][j] == ttt.EMPTY and tiles[i][j].collidepoint(mouse)):
board = ttt.result(board, (i, j))
if game_over:
againButton = pygame.Rect(width / 3, height - 65, width / 3, 50)
again = mediumFont.render("Play Again", True, black)
againRect = again.get_rect()
againRect.center = againButton.center
pygame.draw.rect(screen, white, againButton)
screen.blit(again, againRect)
click, _, _ = pygame.mouse.get_pressed()
if click == 1:
mouse = pygame.mouse.get_pos()
if againButton.collidepoint(mouse):
time.sleep(0.2)
user = None
board = ttt.initial_state()
ai_turn = False
pygame.display.flip()
pygame.mouse.get_pressed()
Returns a sequence of booleans representing the state of all the mouse buttons.
The number of buttons is either 4 or 6, that depends on the version of pygame. I recommend to get the state of a single button by subscription:
buttons = pygame.mouse.get_pressed()
if button[0] == 1:
# [...]
What is returned when you execute pygame.mouse.get_pressed()? I see (0, 0, 0) which is the three arguments your code expects.
You could work out what your code is returning and add the requisite number of underscores, but if you aren't interested in the remaining arguments, you can use * to handle the rest of the returned values, e.g.
click, *_ = pygame.mouse.get_pressed()
Is there a significant difference in term of performance drawing one rectangle for every cell of the grid compared to drawing the grid using horizontal and vertical lines ?
Yes, using lines drawing is one or more order of magnitude faster than drawing rectangles. The code below times both methods.
import pygame
import os
import time
TITLE = "Draw grid"
WINDOWS_LOCATION = '100,100'
WIDTH = 710
HEIGHT = 710
FPS = 1
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
CELL_SIZE = 15
GRID_COORD_MARGIN_SIZE = 20
class Grid():
def __init__(self, surface, cellSize, axisLabels):
self.surface = surface
self.colNb = surface.get_width() // cellSize
self.lineNb = surface.get_height() // cellSize
self.cellSize = cellSize
self.axisLabels = axisLabels
self.grid = [[0 for i in range(self.colNb)] for j in range(self.lineNb)]
self.font = pygame.font.SysFont('arial', 12, False)
def drawUseRect(self):
for li in range(self.lineNb):
liCoord = GRID_COORD_MARGIN_SIZE + li * CELL_SIZE
if self.axisLabels:
if li < 10:
ident = ' '
else:
ident = ' '
text = self.font.render(ident + str(li), 1, (0, 0, 0))
self.surface.blit(text, (0, liCoord))
for co in range(self.colNb):
colCoord = GRID_COORD_MARGIN_SIZE + co * CELL_SIZE
if self.axisLabels:
if co < 10:
ident = ' '
else:
ident = ' '
text = self.font.render(ident + str(co), 1, (0, 0, 0))
self.surface.blit(text, (colCoord, 1))
pygame.draw.rect(self.surface, BLACK, pygame.Rect(liCoord, colCoord, CELL_SIZE, CELL_SIZE), 1)
def drawUseLine(self):
for li in range(self.lineNb):
liCoord = GRID_COORD_MARGIN_SIZE + li * CELL_SIZE
if self.axisLabels:
if li < 10:
ident = ' '
else:
ident = ' '
text = self.font.render(ident + str(li), 1, (0, 0, 0))
self.surface.blit(text, (0, liCoord))
pygame.draw.line(self.surface, BLACK, (GRID_COORD_MARGIN_SIZE, liCoord), (self.surface.get_width(), liCoord))
for co in range(self.colNb):
colCoord = GRID_COORD_MARGIN_SIZE + co * CELL_SIZE
if self.axisLabels:
if co < 10:
ident = ' '
else:
ident = ' '
text = self.font.render(ident + str(co), 1, (0, 0, 0))
self.surface.blit(text, (colCoord, 1))
pygame.draw.line(self.surface, BLACK, (colCoord, GRID_COORD_MARGIN_SIZE), (colCoord,self.surface.get_height()))
# setting Pygame window position (ok on Windows ...)
os.environ['SDL_VIDEO_WINDOW_POS'] = WINDOWS_LOCATION
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(TITLE)
clock = pygame.time.Clock()
running = True
axisLabels = False
grid = Grid(surface=screen, cellSize=CELL_SIZE, axisLabels=axisLabels)
while running:
clock.tick(FPS)
for event in pygame.event.get():
# check for closing window
if event.type == pygame.QUIT:
running = False
screen.fill(WHITE)
start = time.time()
grid.drawUseRect()
print("draw using rect: {}".format(time.time() - start))
start = time.time()
grid.drawUseLine()
print("draw using line: {}".format(time.time() - start))
# *after* drawing everything, flip the display
pygame.display.flip()
pygame.quit()
Here's a example of the timing output on a Windows 10 tablet pc:
draw using rect: 0.04449152946472168
draw using line: 0.0008492469787597656
draw using rect: 0.012907981872558594
draw using line: 0.0
draw using rect: 0.027329683303833008
draw using line: 0.002046346664428711
draw using rect: 0.019585847854614258
draw using line: 0.0009150505065917969
draw using rect: 0.022649049758911133
draw using line: 0.0009458065032958984
draw using rect: 0.022264480590820312
draw using line: 0.0017306804656982422
draw using rect: 0.022340059280395508
draw using line: 0.0009708404541015625
draw using rect: 0.04112124443054199
draw using line: 0.0019001960754394531
And here's a comparison of the visual result of drawing the grid (variable axisLabel set to True):
I'm trying to use check for collision tricks for tkinter. (I don't use pygame) but I need a visible life bar that can change colours. Here's my script:
#Tkinter loader
from tkinter import *
HEIGHT = 500
WIDTH = 800
window = Tk()
window.title ('VOID')
c = Canvas (window, width=WIDTH, height=HEIGHT, bg= 'black')
c.pack()
ship_id = c.create_polygon (5, 5, 5, 25, 25, 25, 25, 5, fill='white')
SHIP_R = 25
MID_X = WIDTH / 2
MID_Y = HEIGHT / 2
c.move (ship_id, MID_X, MID_Y)
# Movment control
SHIP_SPD = 10
def move_ship(event):
if event.keysym == 'w':
c.move (ship_id, 0, -SHIP_SPD)
elif event.keysym == 's':
c.move (ship_id, 0, SHIP_SPD)
elif event.keysym == 'a':
c.move (ship_id, -SHIP_SPD, 0)
elif event.keysym == 'd':
c.move (ship_id, SHIP_SPD, 0)
c.bind_all ('<Key>', move_ship)
# Spawning system (needs copying)
from random import randint
bub_id = list()
bub_r = list()
bub_speed = list()
MIN_BUB_R = 20
MAX_BUB_R = 30
MAX_BUB_SPD = 20
GAP = 100
def create_bubble():
x = WIDTH + GAP
Y = randint (0, HEIGHT)
r = randint (MIN_BUB_R, MAX_BUB_R)
id1 = c.create_polygon (5, 5, 5, 25, 25, 25, 25, 5, fill='lime')
bub_id.append(id1)
bub_r.append(r)
bub_speed.append(randint(1, MAX_BUB_SPD))
def move_bubbles():
for i in range(len(bub_id)):
c.move(bub_id[i], -bub_speed[i], 0)
from time import sleep, time
BUB_CHANCE = 10
#MAIN GAME LOOP
while True:
if randint (1, BUB_CHANCE) == 1:
create_bubble()
move_bubbles()
window.update()
sleep(0.01)
With the fact that both lifebars will go up and down, but at different rates. (so that health takes smaller steps than level.) also with a system were if health or level go to 0 or 100 precent, than something happens like steps. (so you go down a level if the level bar goes to low, and go up a level with the background changing with the lifebar levels.) and the colour will pulse depending on the level you are at.
Thanks.