{"id":100,"date":"2026-05-08T15:11:38","date_gmt":"2026-05-08T15:11:38","guid":{"rendered":"https:\/\/theroyalscode.com\/students\/r_najim\/?p=100"},"modified":"2026-05-08T15:11:39","modified_gmt":"2026-05-08T15:11:39","slug":"friday-may-8-2026","status":"publish","type":"post","link":"https:\/\/theroyalscode.com\/students\/r_najim\/2026\/05\/08\/friday-may-8-2026\/","title":{"rendered":"Friday May, 8, 2026"},"content":{"rendered":"\n<ul class=\"wp-block-list\">\n<li><strong>This Free Friday I am working on a project on YouTube a Space Invaders<\/strong> <strong>game.<\/strong><\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=o-6pADy5Mdg\">https:\/\/www.youtube.com\/watch?v=o-6pADy5Mdg<\/a><\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"301\" height=\"336\" src=\"https:\/\/theroyalscode.com\/students\/r_najim\/wp-content\/uploads\/2026\/05\/image-1.png\" alt=\"\" class=\"wp-image-102\" srcset=\"https:\/\/theroyalscode.com\/students\/r_najim\/wp-content\/uploads\/2026\/05\/image-1.png 301w, https:\/\/theroyalscode.com\/students\/r_najim\/wp-content\/uploads\/2026\/05\/image-1-269x300.png 269w\" sizes=\"auto, (max-width: 301px) 100vw, 301px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>import pygame, sys\nfrom player import Player\nimport obstacle\nfrom alien import Alien, Extra\nfrom random import choice, randint\nfrom laser import Laser\n \nclass Game:\n\tdef __init__(self):\n\t\t# Player setup\n\t\tplayer_sprite = Player((screen_width \/ 2,screen_height),screen_width,5)\n\t\tself.player = pygame.sprite.GroupSingle(player_sprite)\n\n\t\t# health and score setup\n\t\tself.lives = 3\n\t\tself.live_surf = pygame.image.load('..\/graphics\/player.png').convert_alpha()\n\t\tself.live_x_start_pos = screen_width - (self.live_surf.get_size()&#91;0] * 2 + 20)\n\t\tself.score = 0\n\t\tself.font = pygame.font.Font('..\/font\/Pixeled.ttf',20)\n\n\t\t# Obstacle setup\n\t\tself.shape = obstacle.shape\n\t\tself.block_size = 6\n\t\tself.blocks = pygame.sprite.Group()\n\t\tself.obstacle_amount = 4\n\t\tself.obstacle_x_positions = &#91;num * (screen_width \/ self.obstacle_amount) for num in range(self.obstacle_amount)]\n\t\tself.create_multiple_obstacles(*self.obstacle_x_positions, x_start = screen_width \/ 15, y_start = 480)\n\n\t\t# Alien setup\n\t\tself.aliens = pygame.sprite.Group()\n\t\tself.alien_lasers = pygame.sprite.Group()\n\t\tself.alien_setup(rows = 6, cols = 8)\n\t\tself.alien_direction = 1\n\n\t\t# Extra setup\n\t\tself.extra = pygame.sprite.GroupSingle()\n\t\tself.extra_spawn_time = randint(40,80)\n\n\t\t# Audio\n\t\tmusic = pygame.mixer.Sound('..\/audio\/music.wav')\n\t\tmusic.set_volume(0.2)\n\t\tmusic.play(loops = -1)\n\t\tself.laser_sound = pygame.mixer.Sound('..\/audio\/laser.wav')\n\t\tself.laser_sound.set_volume(0.5)\n\t\tself.explosion_sound = pygame.mixer.Sound('..\/audio\/explosion.wav')\n\t\tself.explosion_sound.set_volume(0.3)\n\n\tdef create_obstacle(self, x_start, y_start,offset_x):\n\t\tfor row_index, row in enumerate(self.shape):\n\t\t\tfor col_index,col in enumerate(row):\n\t\t\t\tif col == 'x':\n\t\t\t\t\tx = x_start + col_index * self.block_size + offset_x\n\t\t\t\t\ty = y_start + row_index * self.block_size\n\t\t\t\t\tblock = obstacle.Block(self.block_size,(241,79,80),x,y)\n\t\t\t\t\tself.blocks.add(block)\n\n\tdef create_multiple_obstacles(self,*offset,x_start,y_start):\n\t\tfor offset_x in offset:\n\t\t\tself.create_obstacle(x_start,y_start,offset_x)\n\n\tdef alien_setup(self,rows,cols,x_distance = 60,y_distance = 48,x_offset = 70, y_offset = 100):\n\t\tfor row_index, row in enumerate(range(rows)):\n\t\t\tfor col_index, col in enumerate(range(cols)):\n\t\t\t\tx = col_index * x_distance + x_offset\n\t\t\t\ty = row_index * y_distance + y_offset\n\t\t\t\t\n\t\t\t\tif row_index == 0: alien_sprite = Alien('yellow',x,y)\n\t\t\t\telif 1 &lt;= row_index &lt;= 2: alien_sprite = Alien('green',x,y)\n\t\t\t\telse: alien_sprite = Alien('red',x,y)\n\t\t\t\tself.aliens.add(alien_sprite)\n\n\tdef alien_position_checker(self):\n\t\tall_aliens = self.aliens.sprites()\n\t\tfor alien in all_aliens:\n\t\t\tif alien.rect.right >= screen_width:\n\t\t\t\tself.alien_direction = -1\n\t\t\t\tself.alien_move_down(2)\n\t\t\telif alien.rect.left &lt;= 0:\n\t\t\t\tself.alien_direction = 1\n\t\t\t\tself.alien_move_down(2)\n\n\tdef alien_move_down(self,distance):\n\t\tif self.aliens:\n\t\t\tfor alien in self.aliens.sprites():\n\t\t\t\talien.rect.y += distance\n\n\tdef alien_shoot(self):\n\t\tif self.aliens.sprites():\n\t\t\trandom_alien = choice(self.aliens.sprites())\n\t\t\tlaser_sprite = Laser(random_alien.rect.center,6,screen_height)\n\t\t\tself.alien_lasers.add(laser_sprite)\n\t\t\tself.laser_sound.play()\n\n\tdef extra_alien_timer(self):\n\t\tself.extra_spawn_time -= 1\n\t\tif self.extra_spawn_time &lt;= 0:\n\t\t\tself.extra.add(Extra(choice(&#91;'right','left']),screen_width))\n\t\t\tself.extra_spawn_time = randint(400,800)\n\n\tdef collision_checks(self):\n\n\t\t# player lasers \n\t\tif self.player.sprite.lasers:\n\t\t\tfor laser in self.player.sprite.lasers:\n\t\t\t\t# obstacle collisions\n\t\t\t\tif pygame.sprite.spritecollide(laser,self.blocks,True):\n\t\t\t\t\tlaser.kill()\n\t\t\t\t\t\n\n\t\t\t\t# alien collisions\n\t\t\t\taliens_hit = pygame.sprite.spritecollide(laser,self.aliens,True)\n\t\t\t\tif aliens_hit:\n\t\t\t\t\tfor alien in aliens_hit:\n\t\t\t\t\t\tself.score += alien.value\n\t\t\t\t\tlaser.kill()\n\t\t\t\t\tself.explosion_sound.play()\n\n\t\t\t\t# extra collision\n\t\t\t\tif pygame.sprite.spritecollide(laser,self.extra,True):\n\t\t\t\t\tself.score += 500\n\t\t\t\t\tlaser.kill()\n\n\t\t# alien lasers \n\t\tif self.alien_lasers:\n\t\t\tfor laser in self.alien_lasers:\n\t\t\t\t# obstacle collisions\n\t\t\t\tif pygame.sprite.spritecollide(laser,self.blocks,True):\n\t\t\t\t\tlaser.kill()\n\n\t\t\t\tif pygame.sprite.spritecollide(laser,self.player,False):\n\t\t\t\t\tlaser.kill()\n\t\t\t\t\tself.lives -= 1\n\t\t\t\t\tif self.lives &lt;= 0:\n\t\t\t\t\t\tpygame.quit()\n\t\t\t\t\t\tsys.exit()\n\n\t\t# aliens\n\t\tif self.aliens:\n\t\t\tfor alien in self.aliens:\n\t\t\t\tpygame.sprite.spritecollide(alien,self.blocks,True)\n\n\t\t\t\tif pygame.sprite.spritecollide(alien,self.player,False):\n\t\t\t\t\tpygame.quit()\n\t\t\t\t\tsys.exit()\n\t\n\tdef display_lives(self):\n\t\tfor live in range(self.lives - 1):\n\t\t\tx = self.live_x_start_pos + (live * (self.live_surf.get_size()&#91;0] + 10))\n\t\t\tscreen.blit(self.live_surf,(x,8))\n\n\tdef display_score(self):\n\t\tscore_surf = self.font.render(f'score: {self.score}',False,'white')\n\t\tscore_rect = score_surf.get_rect(topleft = (10,-10))\n\t\tscreen.blit(score_surf,score_rect)\n\n\tdef victory_message(self):\n\t\tif not self.aliens.sprites():\n\t\t\tvictory_surf = self.font.render('You won',False,'white')\n\t\t\tvictory_rect = victory_surf.get_rect(center = (screen_width \/ 2, screen_height \/ 2))\n\t\t\tscreen.blit(victory_surf,victory_rect)\n\n\tdef run(self):\n\t\tself.player.update()\n\t\tself.alien_lasers.update()\n\t\tself.extra.update()\n\t\t\n\t\tself.aliens.update(self.alien_direction)\n\t\tself.alien_position_checker()\n\t\tself.extra_alien_timer()\n\t\tself.collision_checks()\n\t\t\n\t\tself.player.sprite.lasers.draw(screen)\n\t\tself.player.draw(screen)\n\t\tself.blocks.draw(screen)\n\t\tself.aliens.draw(screen)\n\t\tself.alien_lasers.draw(screen)\n\t\tself.extra.draw(screen)\n\t\tself.display_lives()\n\t\tself.display_score()\n\t\tself.victory_message()\n\nclass CRT:\n\tdef __init__(self):\n\t\tself.tv = pygame.image.load('..\/graphics\/tv.png').convert_alpha()\n\t\tself.tv = pygame.transform.scale(self.tv,(screen_width,screen_height))\n\n\tdef create_crt_lines(self):\n\t\tline_height = 3\n\t\tline_amount = int(screen_height \/ line_height)\n\t\tfor line in range(line_amount):\n\t\t\ty_pos = line * line_height\n\t\t\tpygame.draw.line(self.tv,'black',(0,y_pos),(screen_width,y_pos),1)\n\n\tdef draw(self):\n\t\tself.tv.set_alpha(randint(75,90))\n\t\tself.create_crt_lines()\n\t\tscreen.blit(self.tv,(0,0))\n\nif __name__ == '__main__':\n\tpygame.init()\n\tscreen_width = 600\n\tscreen_height = 600\n\tscreen = pygame.display.set_mode((screen_width,screen_height))\n\tclock = pygame.time.Clock()\n\tgame = Game()\n\tcrt = CRT()\n\n\tALIENLASER = pygame.USEREVENT + 1\n\tpygame.time.set_timer(ALIENLASER,800)\n\n\twhile True:\n\t\tfor event in pygame.event.get():\n\t\t\tif event.type == pygame.QUIT:\n\t\t\t\tpygame.quit()\n\t\t\t\tsys.exit()\n\t\t\tif event.type == ALIENLASER:\n\t\t\t\tgame.alien_shoot()\n\n\t\tscreen.fill((30,30,30))\n\t\tgame.run()\n\t\t#crt.draw()\n\t\t\t\n\t\tpygame.display.flip()\n\t\tclock.tick(60)<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>This script builds a full Space\u2011Invaders clone using Pygame. The <strong>Game<\/strong> class manages gameplay, while <strong>CRT<\/strong> adds a retro TV overlay. The main loop updates sprites, checks collisions, spawns aliens, and draws everything.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>import pygame \nfrom laser import Laser\n\nclass Player(pygame.sprite.Sprite):\n\tdef __init__(self,pos,constraint,speed):\n\t\tsuper().__init__()\n\t\tself.image = pygame.image.load('..\/graphics\/player.png').convert_alpha()\n\t\tself.rect = self.image.get_rect(midbottom = pos)\n\t\tself.speed = speed\n\t\tself.max_x_constraint = constraint\n\t\tself.ready = True\n\t\tself.laser_time = 0\n\t\tself.laser_cooldown = 600\n\n\t\tself.lasers = pygame.sprite.Group()\n\n\t\tself.laser_sound = pygame.mixer.Sound('..\/audio\/laser.wav')\n\t\tself.laser_sound.set_volume(0.5)\n\n\tdef get_input(self):\n\t\tkeys = pygame.key.get_pressed()\n\n\t\tif keys&#91;pygame.K_RIGHT]:\n\t\t\tself.rect.x += self.speed\n\t\telif keys&#91;pygame.K_LEFT]:\n\t\t\tself.rect.x -= self.speed\n\n\t\tif keys&#91;pygame.K_SPACE] and self.ready:\n\t\t\tself.shoot_laser()\n\t\t\tself.ready = False\n\t\t\tself.laser_time = pygame.time.get_ticks()\n\t\t\tself.laser_sound.play()\n\n\tdef recharge(self):\n\t\tif not self.ready:\n\t\t\tcurrent_time = pygame.time.get_ticks()\n\t\t\tif current_time - self.laser_time >= self.laser_cooldown:\n\t\t\t\tself.ready = True\n\n\tdef constraint(self):\n\t\tif self.rect.left &lt;= 0:\n\t\t\tself.rect.left = 0\n\t\tif self.rect.right >= self.max_x_constraint:\n\t\t\tself.rect.right = self.max_x_constraint\n\n\tdef shoot_laser(self):\n\t\tself.lasers.add(Laser(self.rect.center,-8,self.rect.bottom))\n\n\tdef update(self):\n\t\tself.get_input()\n\t\tself.constraint()\n\t\tself.recharge()\n\t\tself.lasers.update()<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <code>Player<\/code> object controls:<\/li>\n\n\n\n<li>Movement<\/li>\n\n\n\n<li>Shooting<\/li>\n\n\n\n<li>Laser cooldown<\/li>\n\n\n\n<li>Staying inside the screen<\/li>\n\n\n\n<li>Managing its own lasers<\/li>\n\n\n\n<li>It inherits from <code>pygame.sprite.Sprite<\/code>, which lets it be drawn and updated easily inside a group.<\/li>\n\n\n\n<li>This sets up everything the player needs:<\/li>\n\n\n\n<li>Loads the player image<\/li>\n\n\n\n<li>Positions it using <code>midbottom = pos<\/code><\/li>\n\n\n\n<li>Stores movement speed<\/li>\n\n\n\n<li>Stores the horizontal boundary (<code>max_x_constraint<\/code>)<\/li>\n\n\n\n<li>Sets up shooting cooldown (<code>ready<\/code>, <code>laser_time<\/code>, <code>laser_cooldown<\/code>)<\/li>\n\n\n\n<li>Creates a sprite group to hold all lasers<\/li>\n\n\n\n<li>Loads the laser sound<\/li>\n\n\n\n<li>This makes the player self\u2011contained: it manages its own movement, shooting, and lasers.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>import pygame \n\nclass Laser(pygame.sprite.Sprite):\n\tdef __init__(self,pos,speed,screen_height):\n\t\tsuper().__init__()\n\t\tself.image = pygame.Surface((4,20))\n\t\tself.image.fill('white')\n\t\tself.rect = self.image.get_rect(center = pos)\n\t\tself.speed = speed\n\t\tself.height_y_constraint = screen_height\n\n\tdef destroy(self):\n\t\tif self.rect.y &lt;= -50 or self.rect.y >= self.height_y_constraint + 50:\n\t\t\tself.kill()\n\n\tdef update(self):\n\t\tself.rect.y += self.speed\n\t\tself.destroy()<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A <code>Laser<\/code> is a simple projectile:<\/li>\n\n\n\n<li>It moves straight up or down<\/li>\n\n\n\n<li>It destroys itself when off\u2011screen<\/li>\n\n\n\n<li>It can collide with aliens, obstacles, or the player<\/li>\n\n\n\n<li>It inherits from <code>pygame.sprite.Sprite<\/code> so it can live inside a sprite group and be updated\/drawn automatically.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>import pygame \n\nclass Block(pygame.sprite.Sprite):\n\tdef __init__(self,size,color,x,y):\n\t\tsuper().__init__()\n\t\tself.image = pygame.Surface((size,size))\n\t\tself.image.fill(color)\n\t\tself.rect = self.image.get_rect(topleft = (x,y))\n\nshape = &#91;\n'  xxxxxxx',\n' xxxxxxxxx',\n'xxxxxxxxxxx',\n'xxxxxxxxxxx',\n'xxxxxxxxxxx',\n'xxx     xxx',\n'xx       xx']<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <code>Block<\/code> class represents <strong>one tiny square<\/strong> of the shield\/obstacle.<\/li>\n\n\n\n<li>Each shield is made up of <strong>dozens of these blocks<\/strong> arranged in a pattern.<\/li>\n\n\n\n<li>It creates a square surface (<code>size \u00d7 size<\/code>)<\/li>\n\n\n\n<li>Fills it with a color (usually red\/pink)<\/li>\n\n\n\n<li>Places it at a specific <code>(x, y)<\/code> position on the screen<\/li>\n\n\n\n<li>Because it inherits from <code>pygame.sprite.Sprite<\/code>, it can be added to a sprite group and easily drawn, updated, and destroyed.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>import pygame\n\nclass Alien(pygame.sprite.Sprite):\n\tdef __init__(self,color,x,y):\n\t\tsuper().__init__()\n\t\tfile_path = '..\/graphics\/' + color + '.png'\n\t\tself.image = pygame.image.load(file_path).convert_alpha()\n\t\tself.rect = self.image.get_rect(topleft = (x,y))\n\n\t\tif color == 'red': self.value = 100\n\t\telif color == 'green': self.value = 200\n\t\telse: self.value = 300\n\n\tdef update(self,direction):\n\t\tself.rect.x += direction\n\nclass Extra(pygame.sprite.Sprite):\n\tdef __init__(self,side,screen_width):\n\t\tsuper().__init__()\n\t\tself.image = pygame.image.load('..\/graphics\/extra.png').convert_alpha()\n\t\t\n\t\tif side == 'right':\n\t\t\tx = screen_width + 50\n\t\t\tself.speed = - 3\n\t\telse:\n\t\t\tx = -50\n\t\t\tself.speed = 3\n\n\t\tself.rect = self.image.get_rect(topleft = (x,80))\n\n\tdef update(self):\n\t\tself.rect.x += self.speed<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Alien<\/strong><\/li>\n\n\n\n<li><strong>Extra (UFO)<\/strong>\n<ul class=\"wp-block-list\">\n<li>Special bonus enemy<\/li>\n\n\n\n<li>Spawns from left or right<\/li>\n\n\n\n<li>Moves across the top of the screen<\/li>\n\n\n\n<li>Worth extra points when shot<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Both classes are simple, efficient, and work perfectly with Pygame\u2019s sprite system.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[1],"tags":[],"class_list":["post-100","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/theroyalscode.com\/students\/r_najim\/wp-json\/wp\/v2\/posts\/100","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/theroyalscode.com\/students\/r_najim\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/theroyalscode.com\/students\/r_najim\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/theroyalscode.com\/students\/r_najim\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/theroyalscode.com\/students\/r_najim\/wp-json\/wp\/v2\/comments?post=100"}],"version-history":[{"count":1,"href":"https:\/\/theroyalscode.com\/students\/r_najim\/wp-json\/wp\/v2\/posts\/100\/revisions"}],"predecessor-version":[{"id":103,"href":"https:\/\/theroyalscode.com\/students\/r_najim\/wp-json\/wp\/v2\/posts\/100\/revisions\/103"}],"wp:attachment":[{"href":"https:\/\/theroyalscode.com\/students\/r_najim\/wp-json\/wp\/v2\/media?parent=100"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/theroyalscode.com\/students\/r_najim\/wp-json\/wp\/v2\/categories?post=100"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/theroyalscode.com\/students\/r_najim\/wp-json\/wp\/v2\/tags?post=100"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}