Pine script: Switch trendline based on if statement - if-statement

How do I set my trendline color and plot based on an if statement i.e. if stock data is > 1 year then use trendline 1 else use trendline method 2:
trend_1 = sma(close, 15)
trend_2 = sma(close, 30)
bearish = true
for i = 0 to trendConfirmationLength - 1
bearish := bearish and (close[i] < trend[i])
bullish = not bearish
// Set the color of the plot based on whether we are bullish (green) or not (red)
c = bullish ? color.green : color.red
// Plot the trend line
trend =
if (len(close) > 252)
trend_1
if (len(close) < 252)
trend_2
trend_plot = plot(trend, title='Trend', color = c)
Thanks

trend_1 = sma(close, 15)
trend_2 = sma(close, 30)
float trend = na
if bar_index >= 252
trend := trend_1
else
trend := trend_2
bool foundBearish = false
bool foundBullish = false
for i = 0 to trendConfirmationLength - 1
if close[i] < trend[i]
foundBearish := true
else if close[i] > trend[i]
foundBullish := true
bullish = foundBullish and not foundBearish
bearish = foundBearish and not foundBullish
neutral = not bullish and not bearish
color c = na
if bullish
c := color.green
else if bearish
c := color.red
else if neutral
c := color.blue
trend_plot = plot(trend, title='Trend', color = c)
If all closes within trendConfirmationLength are below trend then foundBearish will be true and foundBullish will be false (and vice versa). If both foundBearsh and foundBullish are true, it means we had closes both above and below trend.
Alternatively you could do this to keep the trend color until a new trend is formed rather than show a neutral color.
color c = na
if bullish
c := color.green
else if bearish
c := color.red
trend_plot = plot(trend, title='Trend', color = fixnan(c))

Related

Space Invaders Game - How can I make it so that the aliens move down for a set distance, then change direction when they drop? [duplicate]

This question already has answers here:
Is it possible to implement gradual movement of an object to given coordinates in Pygame?
(1 answer)
How to make a circle move diagonally from corner to corner in pygame
(1 answer)
How to move the object in squared path repeatedly?
(1 answer)
Closed 5 months ago.
Currently i'm making Space invaders, and I'm having trouble making the aliens move properly from to the side and down the screen. The aliens are supposed to move one direction, then once they hit the edge of the screen they're meant to go down the screen a little bit, then change direction, and repeat this until they get to the bottom of the screen where the player is. So far this is what I have as a part of my code...
for element in smallInvaders:
element.move_ip(dx,dy)
for element in smallInvaders:
if element.bottom > 100:
dy = 0
dx = 1
if element.right >= width or element.left <= 0:
dy += 0.5
dx = 0
invaderDirSwapped = True
for element in medInvaders:
element.move_ip(dx,dy)
if not invaderDirSwapped:
for element in medInvaders:
if element.right >= width or element.left <= 0:
dy += 0.5
dx = 0
invaderDirSwapped = True
for element in bigInvaders:
element.move_ip(dx,dy)
if not invaderDirSwapped:
for element in bigInvaders:
if element.right >= width or element.left <= 0 :
dy += 0.5
dx = 0
invaderDirSwapped = True
Essentially, smallInvaders, medInvaders and bigInvaders are all lists, where each object in the list is a rect object, that act as the aliens. I tried to make it so that I change the direction y value (dy) when the aliens touch the side of the screen (they're originally moving to the left as dx is -1, and dy is 0 initially), then the dy value gets put to 0, when the y value of the aliens hits a specific amount, but this doesn't seem to work, as the next time through when the aliens go from right to left, they either get stuck, or phase off the side of the screen. I understand both if statements are being executed at the same time, but i'm stuck on what to do because of it, and if there are any other solutions towards fixing the problem.
here's my full code...
import pygame
import sys
import time
import random
#initialize pygame
pygame.mixer.init()
pygame.init()
width = 800
height = 600
# set the size for the surface (screen)
screen = pygame.display.set_mode((width, height),pygame.FULLSCREEN)
width = screen.get_width()
height = screen.get_height()
print(width)
print(height)
# set the caption for the screen
pygame.display.set_caption("Space Invaders")
score = 0
def checkCollision(missles, type, score, invader_kill):
for missle in missles:
collision = missle.collidelist((type))
if collision > -1:
type.pop(collision)
invader_kill.play()
missles.remove(missle)
missle.move_ip(0,missleSpeed)
pygame.draw.rect(screen, WHITE, missle,0)
# define colours you will be using
WHITE = (255,255,255)
GREEN = (0,255,0)
RED = (255,0,0)
BLUE = (0,0,255)
BLACK = (0,0,0)
YELLOW = (255,255,0)
shoot_sound = pygame.mixer.Sound("Music-sfx/shoot.wav")
invader_kill = pygame.mixer.Sound("Music-sfx/invaderkilled.wav")
ship_kill = pygame.mixer.Sound("Music-sfx/explosion.wav")
clock = pygame.time.Clock()
FPS = 60
s = 25
#load and scale images
smallInvaderImg = pygame.image.load("images/smallinvader.png")
smallInvaderImg = pygame.transform.scale(smallInvaderImg,(s,s))
medInvaderImg = pygame.image.load("images/crabinvader.png")
medInvaderImg = pygame.transform.scale(medInvaderImg, (s,s))
bigInvaderImg = pygame.image.load("images/biginvader.png")
bigInvaderImg = pygame.transform.scale(bigInvaderImg, (s,s))
shipImg = pygame.image.load("images/ship.png")
shipImg = pygame.transform.scale(shipImg, (60,60))
shieldImg = pygame.image.load("images/shield.png")
shieldImg = pygame.transform.scale(shieldImg , (80,55))
smallInvaders = []
medInvaders = []
bigInvaders = []
enemiesMap = ["sssssssssss",
"mmmmmmmmmmm",
"mmmmmmmmmmm",
"bbbbbbbbbbb"]
invadertype = [smallInvaders,medInvaders,bigInvaders]
dx = -1
dy = 0
x = 240
y = 45
gap = 10
for element in enemiesMap:
for char in element:
if char == "s":
smallInvaders.append(pygame.Rect(x,y,s,s))
elif char == "m":
medInvaders.append(pygame.Rect(x,y,s,s))
elif char == "b":
bigInvaders.append(pygame.Rect(x,y,s,s))
x += s + gap
y += s + gap
x = 240
ship = pygame.Rect(width/2,525,60,60)
shield1 = pygame.Rect(40,370,80,60)
shield2 = pygame.Rect(250,370,80,60)
shield3 = pygame.Rect(460,370,80,60)
shield4 = pygame.Rect(670,370,80,60)
if ship.right == width:
ship.right = width
#missles
maxMissles = 3
missleSpeed = -6
missleWidth = 5
missleHeight = 30
enemmissleWidth = 5
enemmissleHeight = 25
missles = []
missleFired = False
lives = 3
playbutton = pygame.Rect(width/2,height/2,200,90)
playbutton.center = (width/2,height/2)
quitbutton = pygame.Rect(width/2,height/2,200,90)
quitbutton.center = (width/2,height/2+110)
playagn = pygame.Rect(width/2,height/2,235,90)
playagn.center = (width/2,height/2)
playword = pygame.font.Font("pixeltext.ttf", 35)
title = pygame.font.Font("pixeltext.ttf", 80)
quitword = pygame.font.Font("pixeltext.ttf",35)
endscreen = pygame.font.Font("pixeltext.ttf", 90)
playagaintext = pygame.font.Font("pixeltext.ttf", 35)
gameover = pygame.font.Font("pixeltext.ttf",120 )
livestext = pygame.font.Font("pixeltext.ttf",25)
enemMissleFire = False
enemmislist = []
enemymissle = (pygame.Rect(ship.centerx,y,enemmissleWidth,enemmissleHeight))
Cont = False
invaderDirSwapped = False
screenControl = 0
main = True
while main:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
main = False
for element in smallInvaders:
element.move_ip(dx,dy)
for element in smallInvaders:
if element.bottom > 100:
dy = 0
dx = 1
if element.right >= width or element.left <= 0:
dy += 0.5
dx = 0
invaderDirSwapped = True
for element in medInvaders:
element.move_ip(dx,dy)
if not invaderDirSwapped:
for element in medInvaders:
if element.right >= width or element.left <= 0:
dy += 0.5
dx = 0
invaderDirSwapped = True
for element in bigInvaders:
element.move_ip(dx,dy)
if not invaderDirSwapped:
for element in bigInvaders:
if element.right >= width or element.left <= 0 :
dy += 0.5
dx = 0
invaderDirSwapped = True
key_input = pygame.key.get_pressed()
if key_input[pygame.K_RIGHT] and ship.right < width:
ship.move_ip(4,0)
if key_input[pygame.K_LEFT] and ship.left > 0:
ship.move_ip(-4,0)
if key_input[pygame.K_SPACE] and not missleFired:
missleFired = True
enemmissleFire = True
shoot_sound.play()
missles.append(pygame.Rect(ship.centerx,ship.top,missleWidth,missleHeight))
if screenControl == 0:
screen.fill(BLACK)
texttitle = title.render("SPACE INVADERS", True, WHITE)
textrect = texttitle.get_rect()
textrect.center = (width/2, 100)
screen.blit(texttitle,textrect)
if playbutton.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
screenControl = 1
lives = 3
pygame.draw.rect(screen,WHITE,(playbutton), 0)
if playbutton.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen,BLUE, (playbutton), 4)
if quitbutton.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
main = False
pygame.draw.rect(screen,WHITE,(quitbutton), 0)
if quitbutton.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen,BLUE,quitbutton,4)
textplay = playword.render("PLAY", True, BLUE)
textrect2 = textplay.get_rect()
textrect2.center = (width/2,height/2)
screen.blit(textplay,textrect2)
textquit = quitword.render("QUIT",True,BLUE)
textrect3 = textquit.get_rect()
textrect3.center = (width/2,height/2+110)
screen.blit(textquit,textrect3)
if screenControl == 1:
screen.fill(BLACK)
if len(missles) > 0:
if missleFired and missles[-1].bottom < (ship.top - 120) and not key_input[pygame.K_SPACE]:
missleFired = False
if len(missles) == 0:
missleFired = False
for invader in smallInvaders:
screen.blit(smallInvaderImg, invader)
for invader in medInvaders:
screen.blit(medInvaderImg, invader)
for invader in bigInvaders:
screen.blit(bigInvaderImg, invader)
screen.blit(shipImg,ship)
screen.blit(shieldImg,shield1)
screen.blit(shieldImg,shield2)
screen.blit(shieldImg,shield3)
screen.blit(shieldImg,shield4)
allinvaders = [smallInvaders,medInvaders,bigInvaders]
randinvader = random.choice(allinvaders)
if randinvader == smallInvaders:
if len(smallInvaders) >= 1:
abc = random.choice(smallInvaders)
elif randinvader == medInvaders:
if len(medInvaders) >= 1:
abc = random.choice(medInvaders)
elif randinvader == bigInvaders:
if len(bigInvaders) >= 1:
abc = random.choice(bigInvaders)
move and draw missles
enemMissleFire = False
if not enemMissleFire:
if enemymissle.colliderect(ship):
lives -= 1
print(f"Lives: {lives}")
enemymissle.center = (abc.centerx,abc.centery)
time.sleep(0.5)
if enemymissle.top > height:
enemymissle.center = (abc.centerx,abc.centery)
if lives == 0:
ship_kill.play()
screenControl = 3
enemymissle.move_ip(0,-missleSpeed + 1)
pygame.draw.rect(screen, WHITE, enemymissle,0)
liveval = livestext.render(f"Lives: {str(lives)}", True, WHITE)
textlives = liveval.get_rect()
textlives.center = (65,20)
screen.blit(liveval,textlives)
checkCollision(missles,smallInvaders,score,invader_kill)
checkCollision(missles,medInvaders,score,invader_kill)
checkCollision(missles,bigInvaders,score,invader_kill)
if smallInvaders == [] and medInvaders == [] and bigInvaders == []:
screenControl = 2
if screenControl == 2:
screen.fill(BLACK)
if playagn.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
print("GAME START")
screenControl = 1
lives = 3
pygame.draw.rect(screen,WHITE,(playagn),0)
if quitbutton.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
main = False
pygame.draw.rect(screen,WHITE, (quitbutton),0)
if playagn.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen,BLUE,(playagn), 4)
if quitbutton.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen,BLUE,(quitbutton),4)
textend = endscreen.render("YOU WON!", True, WHITE)
textrect4 = textend.get_rect()
textrect4.center = (width/2, 150)
screen.blit(textend,textrect4)
textplayagn = playagaintext.render("PLAY AGAIN", True, BLUE)
textrect5 = textplayagn.get_rect()
textrect5.center = (width/2,height/2)
screen.blit(textplayagn,textrect5)
textquit = quitword.render("QUIT",True,BLUE)
textrect3 = textquit.get_rect()
textrect3.center = (width/2,height/2+110)
screen.blit(textquit,textrect3)
if screenControl == 3:
screen.fill(BLACK)
textgameovr = gameover.render("GAME OVER", True, WHITE)
textrect6 = textgameovr.get_rect()
textrect6.center = (width/2,110)
screen.blit(textgameovr,textrect6)
if quitbutton.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
main = False
pygame.draw.rect(screen,WHITE, (quitbutton),0)
if playagn.collidepoint(pygame.mouse.get_pos()) and pygame.mouse.get_pressed()[0]:
print("GAME START")
screenControl = 1
lives = 3
pygame.draw.rect(screen,WHITE,(playagn),0)
if quitbutton.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen,BLUE,(quitbutton),4)
if playagn.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen,BLUE,(playagn), 4)
textplayagn = playagaintext.render("PLAY AGAIN", True, BLUE)
textrect5 = textplayagn.get_rect()
textrect5.center = (width/2,height/2)
screen.blit(textplayagn,textrect5)
textquit = quitword.render("QUIT",True,BLUE)
textrect3 = textquit.get_rect()
textrect3.center = (width/2,height/2+110)
screen.blit(textquit,textrect3)
pygame.display.update()

how do i make images blit from the centre when using a camera in pygame?

I have an issue I need some help with. When colliding I have an issue, the image is off-centered to the side as when it is blitted it doesn't do it from the centre, so when the sprite collides on one side it goes inwards more than it does on the other side when I just want it to be the same for both sides. It is sort of hard to explain in words. the reason this is an issue and I can't just divide the numbers in the blit command by 2 is because I am using a camera system I found here on stack overflow
this is the key bit in the code that im getting stuck with. I have included all the camera stuff as it may be needed to help
camera.update(player)
for e in lay3:
screen.blit(e.image, camera.apply(e))
# update player, draw everything else
player.update(up, down, left, right, running, platforms)
for e in lay2:
screen.blit(e.image, camera.apply(e))
for e in lay:
screen.blit(e.image, camera.apply(e))
for e in entities:
if e not in lay and e not in lay2 and e not in lay3:
screen.blit(e.image, camera.apply(e))
pygame.display.update()
class Camera(object):
def __init__(self, camera_func, width, height):
self.camera_func = camera_func
self.state = Rect(0, 0, width, height)
def apply(self, target):
return target.rect.move(self.state.topleft)
def update(self, target):
self.state = self.camera_func(self.state, target.rect)
def simple_camera(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h)
def complex_camera(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
l, t, _, _ = -l+HALF_WIDTH, -t+HALF_HEIGHT, w, h
l = min(0, l) # stop scrolling at the left edge
l = max(-(camera.width-WIN_WIDTH), l) # stop scrolling at the right edge
t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling at the bottom
t = min(0, t) # stop scrolling at the top
return Rect(l, t, w, h)
if this is still not enough to solve this is all of the code.
#! /usr/bin/python
import pygame
from pygame import *
WIN_WIDTH = 800
WIN_HEIGHT = 640
HALF_WIDTH = int(WIN_WIDTH / 2)
HALF_HEIGHT = int(WIN_HEIGHT / 2)
idlecount = 0
DISPLAY = (WIN_WIDTH, WIN_HEIGHT)
DEPTH = 32
FLAGS = 0
CAMERA_SLACK = 30
pygame.init()
screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
SAI = [pygame.image.load("samusIdle0.png").convert_alpha(),pygame.image.load("samusIdle1.png").convert_alpha(),pygame.image.load("samusIdle2.png").convert_alpha(),pygame.image.load("samusIdle3.png").convert_alpha(),pygame.image.load("samusIdle0.png").convert_alpha()]
SAIL = [pygame.image.load("Samus0.png").convert_alpha(),pygame.image.load("Samus1.png").convert_alpha(),pygame.image.load("Samus2.png").convert_alpha(),pygame.image.load("Samus3.png").convert_alpha(),pygame.image.load("Samus0.png").convert_alpha()]
def main():
global cameraX, cameraY
global bg
global entities
timer = pygame.time.Clock()
up = down = left = right = running = False
bg = Surface((32,32))
bg.convert()
bg.fill(Color("#000000"))
entities = pygame.sprite.Group()
player = Player(32, 32)
platforms = []
x = y = 0
level = [
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxij",
"x ij",
"xg ij",
"x ij",
"x ij",
"x ij",
"x ij",
"x ij",
"x ij",
"x ij",
"x ij",
"x ij",
"x ij",
"x ij",
"x ij",
"x ij",
"xf ij",
"x ij",
"x Hh",
"x ",
"x ",
"x ",
"PPPPPPPPPPPPPPPPPPPPPV ",
"KMKMKMKMKMKMKMKMKMKMKQ APPPPPPPPPPPPPPPPP",
"MKMKMKMKMKMKMKMKMKMKMSPPPPPPPPPPPPPPPPPPPPPPZMKMKMKMKMKMKMKMKM",]
# build the level
global tile
for row in level:
for col in row:
if col == "P":
tile = 1
p = Platform(x, y)
platforms.append(p)
entities.add(p)
if col == "A":
tile = 13
q = Platform(x, y)
platforms.append(q)
entities.add(q)
if col == "Z":
tile = 14
q = Platform(x, y)
platforms.append(q)
entities.add(q)
if col == "Q":
tile = 2
q = Platform(x, y)
platforms.append(q)
entities.add(q)
if col == "V":
tile = 3
q = Platform(x, y)
platforms.append(q)
entities.add(q)
if col == "S":
tile = 4
q = Platform(x, y)
platforms.append(q)
entities.add(q)
if col == "K":
tile = 5
q = Platform(x, y)
platforms.append(q)
entities.add(q)
if col == "M":
tile = 6
q = Platform(x, y)
platforms.append(q)
entities.add(q)
if col == "h":
tile = 7
q = Platform(x, y)
platforms.append(q)
entities.add(q)
if col == "H":
tile = 8
q = Platform(x, y)
platforms.append(q)
entities.add(q)
if col == "i":
tile = 9
q = Platform(x, y)
platforms.append(q)
entities.add(q)
if col == "j":
tile = 10
q = Platform(x, y)
platforms.append(q)
entities.add(q)
if col == "x":
tile = 11
q = Platform(x, y)
platforms.append(q)
entities.add(q)
if col == "f":
tile = 12
q = Platform(x, y)
entities.add(q)
if col == "g":
tile = 0
q = Platform(x, y)
entities.add(q)
eee = q
print (entities)
if col == "E":
e = ExitBlock(x, y)
platforms.append(e)
entities.add(e)
x += 32
y += 32
x = 0
total_level_width = len(level[0])*32
total_level_height = len(level)*32
camera = Camera(complex_camera, total_level_width, total_level_height)
entities.add(player)
global idlecount
global direction
direction = 'right'
while 1:
timer.tick(60)
idlecount = idlecount + 0.05
if direction == 'right':
player.image = SAIL[int(idlecount)]
if direction == 'left':
player.image = SAI[int(idlecount)]
if idlecount > 4:
idlecount = 0
for e in pygame.event.get():
if e.type == QUIT: raise SystemExit, "QUIT"
if e.type == KEYDOWN and e.key == K_ESCAPE:
raise SystemExit, "ESCAPE"
if e.type == KEYDOWN and e.key == K_UP:
up = True
down = False
if e.type == KEYDOWN and e.key == K_DOWN:
downk = True
if e.type == KEYDOWN and e.key == K_LEFT:
direction = 'left'
left = True
if e.type == KEYDOWN and e.key == K_RIGHT:
right = True
direction = 'right'
if e.type == KEYDOWN and e.key == K_SPACE:
running = True
if e.type == KEYUP and e.key == K_UP:
up = False
down = True
if e.type == KEYUP and e.key == K_DOWN:
downk = False
if e.type == KEYUP and e.key == K_RIGHT:
right = False
if e.type == KEYUP and e.key == K_LEFT:
left = False
# draw background
for y in range(32):
for x in range(32):
screen.blit(bg, (x * 32, y * 32))
camera.update(player)
for e in lay3:
screen.blit(e.image, camera.apply(e))
# update player, draw everything else
player.update(up, down, left, right, running, platforms)
for e in lay2:
screen.blit(e.image, camera.apply(e))
for e in lay:
screen.blit(e.image, camera.apply(e))
for e in entities:
if e not in lay and e not in lay2 and e not in lay3:
screen.blit(e.image, camera.apply(e))
pygame.display.update()
class Camera(object):
def __init__(self, camera_func, width, height):
self.camera_func = camera_func
self.state = Rect(0, 0, width, height)
def apply(self, target):
return target.rect.move(self.state.topleft)
def update(self, target):
self.state = self.camera_func(self.state, target.rect)
def simple_camera(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h)
def complex_camera(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
l, t, _, _ = -l+HALF_WIDTH, -t+HALF_HEIGHT, w, h
l = min(0, l) # stop scrolling at the left edge
l = max(-(camera.width-WIN_WIDTH), l) # stop scrolling at the right edge
t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling at the bottom
t = min(0, t) # stop scrolling at the top
return Rect(l, t, w, h)
class Entity(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
class Player(Entity):
def __init__(self, x, y):
global lay
global lay2
global lay3
global idlecount
Entity.__init__(self)
self.xvel = 0
self.yvel = 0
self.onGround = False
self.image = Surface((32,72))
self.image = SAIL[int(idlecount)]
lay = pygame.sprite.LayeredUpdates()
lay.add(self)
lay2 = pygame.sprite.LayeredUpdates()
lay3 = pygame.sprite.LayeredUpdates()
self.image.convert()
self.rect = Rect(x, y, 32, 72)
def update(self, up, down, left, right, running, platforms):
if up:
# only jump if on the ground
if self.onGround: self.yvel -= 14
if down:
self.yvel += 0.5
if running:
self.xvel = 12
if left:
self.xvel = -8
if right:
self.xvel = 8
if not self.onGround:
# only accelerate with gravity if in the air
down = False
self.yvel += 0.5
# max falling speed
if self.yvel > 100: self.yvel = 100
if not(left or right):
self.xvel = 0
# increment in x direction
self.rect.left += self.xvel
# do x-axis collisions
self.collide(self.xvel, 0, platforms)
# increment in y direction
self.rect.top += self.yvel
# assuming we're in the air
self.onGround = False;
# do y-axis collisions
self.collide(0, self.yvel, platforms)
def collide(self, xvel, yvel, platforms):
for p in platforms:
if pygame.sprite.collide_rect(self, p):
if isinstance(p, ExitBlock):
pygame.event.post(pygame.event.Event(QUIT))
if xvel > 0:
self.rect.right = p.rect.left
print "collide right"
if xvel < 0:
self.rect.left = p.rect.right
print "collide left"
if yvel > 0:
self.rect.bottom = p.rect.top
self.onGround = True
self.yvel = 0
if yvel < 0:
self.rect.top = p.rect.bottom
down = True
for q in platforms:
if pygame.sprite.collide_rect(self, p):
if isinstance(p, ExitBlock):
pygame.event.post(pygame.event.Event(QUIT))
if xvel > 0:
self.rect.right = p.rect.left
print "collide right"
if xvel < 0:
self.rect.left = p.rect.right
print "collide left"
if yvel > 0:
self.rect.bottom = p.rect.top
self.onGround = True
self.yvel = 0
if yvel < 0:
self.rect.top = p.rect.bottom
class Platform(Entity):
global tile
def __init__(self, x, y):
Entity.__init__(self)
self.image = Surface((32, 32))
self.image.convert()
if tile == 1:
self.image = pygame.image.load('tile8.png').convert()
elif tile == 2:
self.image = pygame.image.load('tile7.png').convert()
elif tile == 3:
self.image = pygame.image.load('tile5.png').convert()
elif tile == 4:
self.image = pygame.image.load('tile6.png').convert()
elif tile == 5:
self.image = pygame.image.load('tileA1.png').convert()
elif tile == 6:
self.image = pygame.image.load('tileA2.png').convert()
elif tile == 7:
self.image = pygame.image.load('tile10.png').convert()
elif tile == 8:
self.image = pygame.image.load('tile9.png').convert()
elif tile == 9:
self.image = pygame.image.load('tile11.png').convert()
elif tile == 10:
self.image = pygame.image.load('tile12.png').convert()
elif tile == 11:
self.image = pygame.image.load('tile00.png').convert_alpha()
elif tile == 0:
self.image = pygame.image.load('sky.png').convert_alpha()
lay3.add(self)
elif tile == 12:
self.image = pygame.image.load('samusShip.png').convert_alpha()
lay2.add(self)
elif tile == 13:
self.image = pygame.image.load('tile13.png').convert()
elif tile == 14:
self.image = pygame.image.load('tile14.png').convert()
self.rect = Rect(x, y, 32, 32)
def update(self):
pass
class ExitBlock(Platform):
def __init__(self, x, y):
Platform.__init__(self, x, y)
self.image.fill(Color("#0033FF"))
if __name__ == "__main__":
main()
Thank you for your time,
EDIT:
I should probably mention that the sprites for the player are 52x72 pixels, this creates overhang when touching a wall and I need the overhang to be the same on both sides
You can give the Player class a draw method in which you add an arbitrary offset to the coordinates.
def draw(self, screen, rect):
x, y = rect.topleft
screen.blit(self.image, (x-10, y)) # -10 because the rect is 20 px smaller than the image.
In the main function before pygame.display.update() add the line:
player.draw(screen, camera.apply(player))
Edit: You need to remove the for e in lay: loop which blits the player sprite, otherwise it gets blitted twice.

How to modify a variable when a while loop is running Python

I am using wx.python along with VPython to make an orbit simulator, however i'm having trouble trying to get the sliders in the GUI to effect the simulation, I assume it's because I am trying to get the number associated with the slider button to go into a while loop when it is running.
So my question is, how do i get the function SetRate to update in the while loop located at the bottom of the code? (I have checked to see that the slider is retuning values)
Here is my code for reference:
Value = 1.0
dt = 100.0
def InputValue(Value):
dt = Value
def SetRate(evt):
global Value
Value = SpeedOfSimulation.GetValue()
return Value
w = window(menus=True, title="Planetary Orbits",x=0, y=0, width = 1000, height = 1000)
Screen = display(window = w, x = 30, y = 30, width = 700, height = 500)
gdisplay(window = w, x = 80, y = 80 , width = 40, height = 20)
p = w.panel # Refers to the full region of the window in which to place widgets
SpeedOfSimulation = wx.Slider(p, pos=(800,10), size=(200,100), minValue=0, maxValue=1000)
SpeedOfSimulation.Bind(wx.EVT_SCROLL, SetRate)
TestData = [2, 0, 0, 0, 6371e3, 5.98e24, 0, 0, 0, 384400e3, 0, 0, 1737e3, 7.35e22, 0, 1e3, 0]
Nstars = TestData[0] # change this to have more or fewer stars
G = 6.7e-11 # Universal gravitational constant
# Typical values
Msun = 2E30
Rsun = 2E9
vsun = 0.8*sqrt(G*Msun/Rsun)
Stars = []
colors = [color.red, color.green, color.blue,
color.yellow, color.cyan, color.magenta]
PositionList = []
MomentumList = []
MassList = []
RadiusList = []
for i in range(0,Nstars):
s=i*8
x = TestData[s+1]
y = TestData[s+2]
z = TestData[s+3]
Radius = TestData[s+4]
Stars = Stars+[sphere(pos=(x,y,z), radius=Radius, color=colors[i % 6],
make_trail=True, interval=10)]
Mass = TestData[s+5]
SpeedX = TestData[s+6]
SpeedY = TestData[s+7]
SpeedZ = TestData[s+8]
px = Mass*(SpeedX)
py = Mass*(SpeedY)
pz = Mass*(SpeedZ)
PositionList.append((x,y,z))
MomentumList.append((px,py,pz))
MassList.append(Mass)
RadiusList.append(Radius)
pos = array(PositionList)
Momentum = array(MomentumList)
Mass = array(MassList)
Mass.shape = (Nstars,1) # Numeric Python: (1 by Nstars) vs. (Nstars by 1)
Radii = array(RadiusList)
vcm = sum(Momentum)/sum(Mass) # velocity of center of mass
Momentum = Momentum-Mass*vcm # make total initial momentum equal zero
Nsteps = 0
time = clock()
Nhits = 0
while True:
InputValue(Value) #Reprensents the change in time
rate(100000) #No more than 100 loops per second on fast computers
# Compute all forces on all stars
r = pos-pos[:,newaxis] # all pairs of star-to-star vectors (Where r is the Relative Position Vector
for n in range(Nstars):
r[n,n] = 1e6 # otherwise the self-forces are infinite
rmag = sqrt(sum(square(r),-1)) # star-to-star scalar distances
hit = less_equal(rmag,Radii+Radii[:,newaxis])-identity(Nstars)
hitlist = sort(nonzero(hit.flat)[0]).tolist() # 1,2 encoded as 1*Nstars+2
F = G*Mass*Mass[:,newaxis]*r/rmag[:,:,newaxis]**3 # all force pairs
for n in range(Nstars):
F[n,n] = 0 # no self-forces
Momentum = Momentum+sum(F,1)*dt
# Having updated all momenta, now update all positions
pos = pos+(Momentum/Mass)*dt
# Update positions of display objects; add trail
for i in range(Nstars):
Stars[i].pos = pos[i]
I know nothing about vpython but in a normal wxPython app, you will use wx.Timer instead of while loop.
here is an example of wx.Timer modified from https://www.blog.pythonlibrary.org/2009/08/25/wxpython-using-wx-timers/
You will want to separate the while loop part from your SetRate class method and put it in update.
import wx
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "Timer Tutorial 1",
size=(500,500))
# Add a panel so it looks the correct on all platforms
panel = wx.Panel(self, wx.ID_ANY)
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.update, self.timer)
SpeedOfSimulation = wx.Slider(p, pos=(800,10), size=(200,100), minValue=0, maxValue=1000)
SpeedOfSimulation.Bind(wx.EVT_SCROLL, SetRate)
self.SpeedOfSimulation = SpeedOfSimulation
def update(self, event):
# Compute all forces on all stars
SpeedOfSimulation = self.SpeedOfSimulation.GetValue()

If/else statement Lua

Each time the arithmetic question is generated and whenever i pick the right or wrong answer the statement of function checkanswer() always goes on if-statement "Correct". How am i able to create if/else statement correctly base on an arithmetic question varanswer = var1 + var2
function checkAnswer(event)
if(#theAnswer == questionGen()) then
instructionsText.text = "Correct!";
instructionsText:toFront()
generateBalls()
for i=1, allBallsGroup.numChildren do
display.remove(allBallsGroup[1])
end
else
instructionsText.text = "Incorrect!";
instructionsText:toFront()
generateBalls()
for i=1, allBallsGroup.numChildren do
display.remove(allBallsGroup[1])
end
end
end
function questionGen()
local questionVar1 = display.newImage("ygSquare.png", 150, 500);
local var1 = math.random(1,9)
local var1Display =display.newText(var1, 200, 500, native.systemFont, 200)
questionVar1.width = 200
questionVar1.height = 200
questionVar1.x = 350
questionVar1.y = 500
var1Display.x = 350
var1Display.y = 500
var1Display:setTextColor("#000000")
local questionVar2 = display.newImage("blueSquare.png", 150, 500);
local var2 = math.random(1,9)
local var2Display = display.newText(var2, 200, 500, native.systemFont, 200)
questionVar2.width = 200
questionVar2.height = 200
questionVar2.x = 700
questionVar2.y = 500
var2Display.x = 700
var2Display.y = 500
var2Display:setTextColor("#000000")
local operator = " + "
local operatorDisplay = display.newText(operator, 400, 500, native.systemFont, 200)
operatorDisplay:setTextColor("#000000")
local varAnswer = var1 + var2
return varAnswer
end
Your random values are greater than 1 and adding two numbers greater than 1, will be greater than 1. This means that questionGen() is always returning true. I would divide var1 and var2 by 9 so that it is normalized. Also you will need to add a line to check if varAnswer say greater than 1 (0.5+05) return true else return false.
function questionGen()
local varAnswer = var1/9 + var2/9
if(varAnswer>=1) then return true end
return false
end
Now in your other function you can check if(questionGen()) then
This is use to create inputs or choices in my game macro
local theAnswer= "";
local theAnswerText;
function createBall()
local var numberArray = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "11", "12", "13", "14", "15", "16", "17", "18"};
local tens = {questionGen(#theAnswer)}
local ballType = math.random(8);
local ballSize = math.random(2)
local letterIndex
local letter
if(createTens == true) then
letterIndex = math.random(#tens)
letter = tens[letterIndex];
else
letterIndex = math.random(#numberArray);
letter = numberArray[letterIndex];
letterIndex = math.random(#tens)
letter = tens[letterIndex];
end
local ballGroup = display.newGroup();
local ball
local ballRadius
if(ballType == 1) then
ball = display.newImage("whiteBall.png");
elseif(ballType == 2) then
ball = display.newImage("brownBall.png");
elseif(ballType == 3) then
ball = display.newImage("pinkBall.png");
elseif(ballType == 4) then
ball = display.newImage("whiteBall.png");
elseif(ballType == 5) then
ball = display.newImage("yellowBall.png");
elseif(ballType == 6) then
ball = display.newImage("whiteBall.png");
elseif(ballType == 7) then
ball = display.newImage("greenBall.png");
else
ball = display.newImage("redBall.png");
end
if(ballSize == 1)then
ball.width = 200;
ball.height = 200;
ballRadius = 30;
else
ball.width = 200;
ball.height = 200;
ballRadius = 30;
end
local letterText = display.newText( letter, 0,0, native.systemFontBold, 100 );
letterText:setTextColor(0,0, 0);
letterText.x = ball.x;
letterText.y = ball.y;
ballGroup:insert(ball);
ballGroup:insert(letterText);
ballGroup.x = math.random(ballRadius,display.contentWidth-ballRadius*3);
ballGroup.y= 40;
physics.addBody(ballGroup, 'dynamic',{friction = 0,bounce = 0,radius = ballRadius*3});
ballGroup.name = "ball";
ballGroup.letter = letter;
ballGroup:addEventListener('tap',checkAnswer);
table.insert(allBalls,ballGroup)
allBallsGroup:insert(ballGroup)
end

Can not to draw all rectangles on the list

The problem is next, I have a list "enemy" and I am adding rectangles to it. After I am finished adding rectangles I need everything on the list to be drawn using the .draw() function that is part of the Enemy class.
# Colour
# Created by Niktia Kotter
#!/usr/bin/env python
import pygame, sys, random, time
from pygame.locals import*
# set up pygame
pygame.init()
FPS=60
fpsclock = pygame.time.Clock()
# R G B
WHITE = (255, 255, 255)
GREEN = (78, 255, 87)
YELLOW = (241, 255, 0)
BLUE = (80, 255, 239)
PURPLE = (203, 0, 255)
RED = (237, 28, 36)
SCREEN_W = 800
SCREEN_H = 480
SCREEN = pygame.display.set_mode((SCREEN_W,SCREEN_H),0,32)
snapMult = SCREEN_W / 5
pos0 = 0
pos1 = snapMult
pos2 = pos1 + snapMult
pos3 = pos2 + snapMult
pos4 = pos3 + snapMult
# set up calsses
class Actor:
def __init__ (self,sizeX,sizeY,colour,positionX,positionY):
self.sizeX = sizeX
self.sizeY = sizeY
self.colour = colour
self.positionX = positionX
self.positionY = positionY
def move(self, dx, i):
self.positionX += dx
self.location = i
def draw(self):
pygame.draw.rect(SCREEN, self.colour, (self.positionX, self.positionY, self.sizeX, self.sizeY))
return
class Enemy:
def __init__ (self,sizeX,sizeY,colour,positionX,positionY):
self.sizeX = sizeX
self.sizeY = sizeY
self.colour = colour
self.positionX = positionX
self.positionY = positionY
def move(self, dy, i):
self.positionY += dy
self.location = i
def draw(self):
pygame.draw.rect(SCREEN, self.colour, (self.positionX, self.positionY, self.sizeX, self.sizeY))
return
class Capture(object):
def __init__(self):
self.caption = pygame.display.set_caption('Space Invaders')
self.screen = SCREEN
self.startGame = True
self.gameOver = False
self.enemyCount = 0
def main(self):
clock = pygame.time.Clock()
actor =[]
enemy =[]
#enemy.append(Enemy(snapMult/20,snapMult/20,RED,pos1,SCREEN_H/2))
#print(enemy, sep='\n')
actor.append(Actor(snapMult,snapMult/2,RED,pos2,SCREEN_H-(snapMult/2)))
while True:
if self.startGame:
SCREEN.fill(WHITE)
actor[0].draw()
if self.enemyCount != 5 or self.enemyCount > 5:
num = random.randint(1, 5)
if num == 0:
print (0)
enemy.append(Enemy(snapMult/20,snapMult/20,RED,pos0,SCREEN_H/2))
if num == 1:
print (1)
enemy.append(Enemy(snapMult/20,snapMult/20,RED,pos1,SCREEN_H/2))
if num == 2:
print (2)
enemy.append(Enemy(snapMult/20,snapMult/20,RED,pos2,SCREEN_H/2))
if num == 3:
print (3)
enemy.append(Enemy(snapMult/20,snapMult/20,RED,pos3,SCREEN_H/2))
if num == 4:
print (4)
enemy.append(Enemy(snapMult/20,snapMult/20,RED,pos4,SCREEN_H/2))
print(enemy, sep='\n')
#for i in range(10):
# x = enemy[i]
# x.draw()
#for Enemy in enemy:
# Enemy.draw()
self.enemyCount += 1
for event in pygame.event.get():
if actor[0].positionX != pos4 and (event.type == KEYDOWN) and (event.key == K_d):
actor[0].move(snapMult,0)
if actor[0].positionX != pos0 and(event.type == KEYDOWN) and (event.key == K_a):
actor[0].move(-snapMult,0)
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
fpsclock.tick(FPS)
if __name__ == '__main__':
game = Capture()
game.main()
Use a simple for loop:
for e in enemy:
e.draw()
Another way is to let your classes inherit from Sprite, and use a Group instead of an ordinay list, so you can use the draw() function of the Group.
Also, I don't think you want to call move on every event. You usually update the game state once per loop iteration, since e.g. moving the mouse generates a lot of events.