First of all, you need to rotate around the center of the triangle. Probably a centroid is best suited for this. To find this, you can use the formula C = (1/3*(x0 + x1 + x2), 1/3*(y0 + y1 + y2)) , since it is the average value for all points of the triangle. Then you need to apply the rotation with this point as the center. So it will be something like this ...
import math class Ship: def centroid(self): return 1 / 3 * (self.x0 + self.x1 + self.x2), 1 / 3 * (self.y0 + self.y1 + self.y2) def __init__(self, canvas, x, y, width, height, turnspeed, acceleration=1): self._d = {'Up':1, 'Down':-1, 'Left':1, 'Right':-1} self.canvas = canvas self.width = width self.height = height self.speed = 0 self.turnspeed = turnspeed self.acceleration = acceleration self.x0, self.y0 = x, y self.bearing = -math.pi / 2 self.x1 = self.x0 + self.width / 2 self.y1 = self.y0 - self.height self.x2 = self.x0 + self.width self.y2 = self.y0 self.x, self.y = self.centroid() self.ship = self.canvas.create_polygon((self.x0, self.y0, self.x1, self.y1, self.x2, self.y2), outline="white", width=3) def changeCoords(self): self.canvas.coords(self.ship,self.x0, self.y0, self.x1, self.y1, self.x2, self.y2) def rotate(self, event=None): t = self._d[event.keysym] * self.turnspeed * math.pi / 180
I made some changes to the controls, which, by the way, make the game more like asteroids. (However, I didn’t realize the shooting. Perhaps I got more in this than I expected, but I am not going to do everything. In addition, there is a small problem when you try to use several navigation keys at once, but what about the way Tk handles events, it was not intended for games, so you will need to fight for a fair bit in order to work normally with Tk / Tkinter.)
from tkinter import * from ship import * class Game: def __init__(self, gameWidth, gameHeight): self.root = Tk() self.gameWidth = gameWidth self.gameHeight = gameHeight self.gameWindow() self.ship = Ship(self.canvas, x=self.gameWidth / 2,y=self.gameHeight / 2, width=50, height=50, turnspeed=10, acceleration=5) self.root.bind('<Left>', self.ship.rotate) self.root.bind('<Right>', self.ship.rotate) self.root.bind('<Up>', self.ship.accel) self.root.bind('<Down>', self.ship.accel) self.root.mainloop() def gameWindow(self): self.frame = Frame(self.root) self.frame.pack(fill=BOTH, expand=YES) self.canvas = Canvas(self.frame,width=self.gameWidth, height=self.gameHeight, bg="black", takefocus=1) self.canvas.pack(fill=BOTH, expand=YES) asteroids = Game(600,600)
Aside, you can use properties to simplify the processing of points, etc.