{"id":3129,"date":"2019-08-25T06:58:00","date_gmt":"2019-08-25T04:58:00","guid":{"rendered":"https:\/\/pythonprogramming.altervista.org\/?p=3129"},"modified":"2020-12-01T11:44:18","modified_gmt":"2020-12-01T10:44:18","slug":"python-snake-game","status":"publish","type":"post","link":"https:\/\/pythonprogramming.altervista.org\/python-snake-game\/","title":{"rendered":"Python Snake game"},"content":{"rendered":"<p>Let&#8217;s start using pygame to make games! Pretty fun assured.<\/p>\n<ul>\n<li><a href=\"https:\/\/pythonprogramming.altervista.org\/python-snake-game\/\">Python Snake game<\/a><\/li>\n<li><a href=\"https:\/\/pythonprogramming.altervista.org\/snake-version-1\/\">Snake version 1<\/a><\/li>\n<li><a href=\"https:\/\/pythonprogramming.altervista.org\/snake-version-2\/\">Snake version 2<\/a><\/li>\n<li><a href=\"https:\/\/pythonprogramming.altervista.org\/snake-game-version-3-with-experimental-music\/\">Snake Game version 3 with (experimental) music<\/a><\/li>\n<li><a href=\"https:\/\/pythonprogramming.altervista.org\/making-snake-game-part-1-the-menu\/\">Making Snake game Part 1: the menu<\/a><\/li>\n<li><a href=\"https:\/\/pythonprogramming.altervista.org\/python-vs-snake-v-1-8-3\/\">Python vs. Snake\u00a0 v. 1.8.3<\/a><\/li>\n<li><a href=\"https:\/\/pythonprogramming.altervista.org\/pysnake-1-8-7\/\">PySnake 1.8.7<\/a><\/li>\n<li><a href=\"https:\/\/pythonprogramming.altervista.org\/a-bigger-snake-game\/\">A bigger Snake Game<\/a><\/li>\n<li><a href=\"https:\/\/pythonprogramming.altervista.org\/pysnake-devlog-3-8-2020-gameover-scene\/\">PySnake gameover scene<\/a> (devlog)<\/li>\n<li><a href=\"https:\/\/pythonprogramming.altervista.org\/pysnake-devlog-1-9-6\/\">Pysnake devlog 1.9.6<\/a><\/li>\n<li><a href=\"https:\/\/pythonprogramming.altervista.org\/looking-for-fluid-movements-in-snake\/\">Looking for fluid movements in snake<\/a><\/li>\n<li><a href=\"https:\/\/pythonprogramming.altervista.org\/pysnake-2-0-3-music-and-fly\/\">PySnake 2.0.3 music and fly<\/a><\/li>\n<\/ul>\n<p><a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2020\/08\/snake202cover800x600.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-6997\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2020\/08\/snake202cover800x600.png\" alt=\"\" width=\"227\" height=\"170\" srcset=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2020\/08\/snake202cover800x600.png 800w, https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2020\/08\/snake202cover800x600-320x240.png 320w, https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2020\/08\/snake202cover800x600-768x576.png 768w\" sizes=\"auto, (max-width: 227px) 100vw, 227px\" \/><\/a><a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2020\/08\/digging.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-6835\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2020\/08\/digging.png\" alt=\"\" width=\"162\" height=\"169\" srcset=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2020\/08\/digging.png 796w, https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2020\/08\/digging-320x334.png 320w, https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2020\/08\/digging-768x801.png 768w\" sizes=\"auto, (max-width: 162px) 100vw, 162px\" \/><\/a><\/p>\n<p>Our first &#8220;<strong>real game<\/strong>&#8221; is a classic and is the Snake. In this classic game from the 80ies, you had to move a snake in a rectangular area to eat a fruit and as you go on with the game you become longer and faster. The problem is that you cannot hit the borders or yourself.<\/p>\n<figure id=\"attachment_3132\" aria-describedby=\"caption-attachment-3132\" style=\"width: 387px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/08\/snake.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-3132 size-full\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/08\/snake.png\" alt=\"\" width=\"387\" height=\"318\" srcset=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/08\/snake.png 387w, https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/08\/snake-320x263.png 320w\" sizes=\"auto, (max-width: 387px) 100vw, 387px\" \/><\/a><figcaption id=\"caption-attachment-3132\" class=\"wp-caption-text\">An image of this very complex game<\/figcaption><\/figure>\n<h2>Create the window<\/h2>\n<p>Let&#8217;s make something that could be the <strong>starting<\/strong> point for a lot of games: define a <strong>window<\/strong> that you can close.<\/p>\n<pre class=\"lang:default decode:true\">import pygame\r\n\r\npygame.init()\r\nwindow = pygame.display.set_mode((400,400))\r\nclock = pygame.time.Clock()\r\nloop = True\r\nwhile loop:\r\n\tfor event in pygame.event.get():\r\n\t\tif event.type == pygame.QUIT:\r\n\t\t\tloop = False\r\npygame.quit()<\/pre>\n<h2>Initialize the code with pygame.init()<\/h2>\n<pre class=\"lang:default decode:true\">pygame.init()<\/pre>\n<p>This will initialize <strong>pygame<\/strong>, making everything work fine so that you can use things like fonts etc. To use the fonts you can also use <strong>pygame.font.init()<\/strong>, but using pygame.init() makes this not necessary.<\/p>\n<h2>Window surface settings or display.set_mode(())<\/h2>\n<pre class=\"lang:default decode:true\">window = pygame.display.set_mode((400,400))<\/pre>\n<p>There is also the <strong>pygame.display.set_caption(&#8220;Title&#8221;)<\/strong>\u00a0to give a name to the window. But we will do it later, maybe.<\/p>\n<h2>The time.Clock()<\/h2>\n<p>This is the <strong>frame rate<\/strong>. The <strong>higher<\/strong> it is the <strong>faster<\/strong> the window will be refreshed. Think to the game as a serious of <strong>frames<\/strong> (static pictures) that are <strong>updated<\/strong> on the screen one after another giving the sensation of movement (like the frames of a movie, if you take them one by one they are pictures that have little differences among them).<\/p>\n<pre class=\"lang:default decode:true \">clock = pygame.time.Clock()<\/pre>\n<p>We will use the frame rate fps to increase the difficulty of the game.<\/p>\n<h2>The loop&#8230; while loop<\/h2>\n<p>This is the part that makes the <strong>sprite move<\/strong> and check if the user moves it, where the sprites are, if they collide, if the snake goes out of the screen. Now there is nothing of this. It just looks if the user clicks the quit button (the x of the window). If you do not write this code you cannot close the window without making the window crash.<\/p>\n<pre class=\"lang:default decode:true \">loop = True\r\nwhile loop:\r\n\tfor event in pygame.event.get():\r\n\t\tif event.type == pygame.QUIT:\r\n\t\t\tloop = False\r\npygame.quit()<\/pre>\n<p>If <strong>loop<\/strong> is <strong>True<\/strong> the window <strong>runs<\/strong>, when loop is <strong>false<\/strong> (you press quit button) the window <strong>quits<\/strong>.<\/p>\n<div style=\"width: 747px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-3129-1\" width=\"747\" height=\"420\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/08\/output0.mp4?_=1\" \/><a href=\"https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/08\/output0.mp4\">https:\/\/pythonprogramming.altervista.org\/wp-content\/uploads\/2019\/08\/output0.mp4<\/a><\/video><\/div>\n<h2>Adding the keys<\/h2>\n<p>Now we want to make the code look readable. Let&#8217;s put the <strong>screen<\/strong> and <strong>clock<\/strong> into a <strong>class<\/strong> called <strong>Game<\/strong><\/p>\n<pre class=\"lang:default decode:true\">import pygame\r\nfrom dataclasses import dataclass\r\n\r\n@dataclass\r\nclass Game:\r\n    \"\"\"A class for the screen and clock\"\"\"\r\n    pygame.init()\r\n    screen = pygame.display.set_mode((400,400))\r\n    clock = pygame.time.Clock()<\/pre>\n<p>I am using <strong>@dataclass<\/strong> to use a type of class that is avaiable from <strong>Python 3.7<\/strong> and that makes me save some memory.<\/p>\n<p>Now the screen will be avaiable as <strong>Game.screen<\/strong> and the clock as <strong>Game.clock<\/strong>.<\/p>\n<p>This is the part of the code where the loop starts and the game waits for an input of the user, listening to the pygame events and making a for loop in pygame.event.get() that :<\/p>\n<pre class=\"lang:default decode:true\">loop = True\r\nwhile loop:\r\n    for event in pygame.event.get():\r\n        if event.type == pygame.QUIT: # Quit button (exit)\r\n            loop = False<\/pre>\n<p>I want to make a nicer keys control code:<\/p>\n<pre class=\"lang:default decode:true\"># =========== Loop Start ======= #\r\nloop = True\r\nwhile loop:\r\n    for event in pygame.event.get():\r\n        quit = event.type == pygame.QUIT\r\n        pressed = pygame.key.get_pressed()\r\n        if quit: loop = False\r\n        elif (event.type == pygame.KEYDOWN): # Arrow keys (move)\r\n            if pressed[pygame.K_RIGHT]: print(\"RIGHT\")\r\n            if pressed[pygame.K_UP]:    print(\"UP\")\r\n            if pressed[pygame.K_DOWN]:  print(\"DOWN\")\r\n            if pressed[pygame.K_LEFT]:  print(\"LEFT\")<\/pre>\n<p>The Whole code is this:<\/p>\n<pre class=\"lang:default decode:true \">import pygame\r\nfrom dataclasses import dataclass\r\n\r\n@dataclass\r\nclass Game:\r\n    \"\"\"A class for the screen and clock\"\"\"\r\n    pygame.init()\r\n    screen = pygame.display.set_mode((400,400))\r\n    clock = pygame.time.Clock()\r\n\r\n# =========== Loop Start ======= #\r\nloop = True\r\nwhile loop:\r\n    for event in pygame.event.get():\r\n        quit = event.type == pygame.QUIT\r\n        pressed = pygame.key.get_pressed()\r\n        if quit: loop = False\r\n        elif (event.type == pygame.KEYDOWN): # Arrow keys (move)\r\n            if pressed[pygame.K_RIGHT]: print(\"RIGHT\")\r\n            if pressed[pygame.K_UP]:    print(\"UP\")\r\n            if pressed[pygame.K_DOWN]:  print(\"DOWN\")\r\n            if pressed[pygame.K_LEFT]:  print(\"LEFT\")\r\n\r\n\r\n# ======================== when the loops ends, goes here =======\r\npygame.quit()\r\n<\/pre>\n<p>Now this code just make a window appear and when you hit the arrow keys it prints up, right, left and down. This means that it works. Now we just have to add the code to move our sprite.<\/p>\n<p>To be continued&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"Snake classic videogame\n<a class=\"moretag\" href=\"https:\/\/pythonprogramming.altervista.org\/python-snake-game\/\"> [...]<\/a>","protected":false},"author":1,"featured_media":3160,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[1,154],"tags":[521,194,520],"class_list":["post-3129","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-examples","category-games","tag-game-python","tag-pygame","tag-snake"],"avopt_banners_inside_post":true,"avopt_banners_on_page":true,"av_copy_from":"","av_sharing_message":"","av_sharing_allowed":false,"av_sharing_on":{"fb":[],"tw":[]},"av_allow_affiliate_banner":false,"av_allow_affiliate_multi_banner":false,"av_show_affiliation_buy_button":false,"av_post_rating":true,"av_have_post_rating_value":false,"av_is_artificial_intelligence_content":false,"_links":{"self":[{"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/posts\/3129","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/comments?post=3129"}],"version-history":[{"count":19,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/posts\/3129\/revisions"}],"predecessor-version":[{"id":7774,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/posts\/3129\/revisions\/7774"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/media\/3160"}],"wp:attachment":[{"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/media?parent=3129"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/categories?post=3129"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pythonprogramming.altervista.org\/wp-json\/wp\/v2\/tags?post=3129"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}