midterm webinar transcript - introduction to programming one ============================================================ presenter: prashant thattai (module leader) topic: midterm submission requirements for side-scrolling game project --- Right, so, good morning, good afternoon, good evening, I'm Prashant Tatakotavikkmar, I'm the module leader for this. We see some tutors who've joined the discussion today. I'm going to pop a quick link for a code-along session that we'll start, we'll be doing for this session, so please look at the, Good morning. So I've popped a message for the code-along session, and we'll pick that up, later on in the talk. Alright, so let's start… Okay, so, so welcome to the midterm webinar for Introduction to Programming One. The main purpose of this webinar is to brief you on the details and the requirements for, the upcoming midterm submission, which would be the site-scrolling game level that you've been developing over the last 5 to 10 weeks. I'm Prashant, the module leader for this course. We're joined by some, some of the tutors that you would be aware of, Kanos, Vincent, Subritha, and George. Hello to all the tutors. So, the structure of this, the structure of this talk, essentially, is that, I'll cover the main requirements for the submission, and we'll do a code-along activity. Following this code-along activity, following this code-along activity, we'll have a question and answer session. In the meantime, if you have any questions that, about the upcoming assessment that you really want to ask, you can pop that in the Q&A, box, or you can pop that in the chat, and one of the tutors would come around and respond. sorry, there's a Q&A, you should have a Q&A, tab available to you, so I would suggest popping it in the Q&A tab, and one of the tutors would respond to you. Alright, so let's get started. A little bit about me, I'm Prashant, I'm the module leader for this course, as well as a lecturer in computer science at Goldsmiths. I work on creative computing applied to music, which essentially means building programs that generate interesting kinds of music. The main agenda for the task today is to quickly review where we are in the course. work through some of the tasks… work through some of the concepts through a code-along task, then I'll describe the project requirements, as well as some of the grading criteria we looked at… look at, and then describe some of the frequently asked questions. But we can always circle around at the end for more questions. Okay. So, so we… I would say we are roughly at the halfway point of the course. Around this point, we've… you've covered most of the fundamentals of programming in P5.js. From the beginning, at the start of the course. you begin applying basic drawing functions, such as creating rectangles and triangles, and then applying them to create game scenery. From then on, you moved on to understand the concept of variables, and how these apply to the design of a game character. In particular, variables store information about character states, such as whether the character is moving up, moving down, looking left, looking right, and so on. Variables combined with conditionals were used to make decisions about what the character behaves, how the character behaves on the screen. This involves, user… this enables user interaction, for instance. By pressing the left key, the character will move towards the left side of the screen, the right key, right side of the screen, and so on. From then on, you started looking at how to create a more complex game scenery using… and arrays were particularly useful for this. Arrays, along with for loops, enable repetitive operations To create a wide array of objects, a wide variety of, a vast number of objects using procedural techniques. In this particular submission, you would use the concept of arrays and for loops in order to generate scenery elements, such as trees, mountains, and clouds. From then on, you moved on to understanding how to store multidimensional information about real-world objects, through objects. Real-world entities through objects. Objects are a way to encapsulate information, they pack information through attributes and features and their values for a specific real-world entity. For example, a cloud can be stored using an X position, a Y position, as well as a size. And maybe other attributes that, That describe the location as well as the size and the color of a cloud screen. So these… we are roughly at a point where we've covered all of this, and this would be sufficient in order to Build a good enough project that you can submit. Moving on, you will learn about more advanced concepts on how to modularly write code using functions, and how to build more complex objects, and many types of complex objects using factory and constructors. But those are for the next submission. Alongside the fundamentals of code, you would have also encountered programming philosophy videos, which give you a sense of how to debug code, as well as how to write program in a way that is error-free. In the code-along session later on, I will also pause and show you how to write code by verifying the outputs at each step and ensuring that your code is error-free as you build it to a more complex, to more complex behaviors. The next big upcoming thing for you is the game project, which is due on the 7th of January. The, time would be 1.59 on UK. I would suggest you to look at Coursera to, understand how that particular time applies to the time zone that you're in. The main, deliverable for this is the side-scroller game that you've been developing. The game has several elements, such as scrolling and interaction with user commands. The game character exists in a scenery that has canyons, collectibles, as well as interaction between the game character and the canyons, as well as clouds. Which are a part of scenery elements. The submissions for this would have happened step-by-step, with peer assessments, that you would have encountered. Here is a link for you to look at some of the past CAME projects that have been, submitted, that hopefully gives you a sense, that hopefully gives you A sense of the kinds of work that have been submitted, and as useful inspiration for you to, Build your own keeps. So I see a few questions and answers that have popped up. If tutors want to pick that up at some point, please do. If you want to leave it to the end, then I'll anyway circle back and start answering those. Alright, so let's go to a quick codalog. go to a quick code-along activity. So we're gonna, through this activity, we'll refresh some of the concepts that you've encountered so far. This particular activity that we're doing is a two-player game in P5JS. It's in the style of Dungeons & Dragons, where it's a die-casting game. There are two characters, a wizard that's controlled by the user, and a goblin that's controlled by the computer. Each of them start off with a certain amount of health, and each of them cast a die to inflict damage on the other character. The person who, whose health reaches zero loses the key, and the other person wins. There are a few rules for how to, how the die casting happens, and how points are knocked off. We'll look at that in the coding example. A few other things to note is the player's interaction with… the player's interaction with the wizard would be through clicking the roll button. This is done through a combination of collision detection, as well as, mouse interaction. The, that has… in order to implement this game, we would also have to implement turn-taking, which is a passing of whose turn is it to cast the right and inflict the wounds. So we'll use variables to store information about whose turn is it, as well as the game state. Conditional will be used to determine, when the game is won or lost. Along with random numbers which create a sense of unpredictability in the game, in terms of who can win or lose. So let's, let's go to P5JS. I've popped the link for you in the chat, so if you scroll to the beginning of the chart, you will find a link to this particular game. Let me pop that again so that you can Access that. Okay. So let's quickly look at the code and how it's organized. This is the initial starting screen from which we'll begin the code. We have the variable game state that stores information about the turns, or the VIN works condition. We have a variable for the die that's a 20-sided die that we are using, which means numbers go from 1 to 20. We have two variables to store the wizard's health and the goblin's health. And finally, a roll button, which is an object that contains information about the features of roll. So let's look at the rules of the game. When the goblin rolls a number that's less than 7, then no damage is inflicted on the wizard. If the number is greater than 13, then twice the damage is inflicted. Otherwise, if the number is between 7 and 13, then the value of the die is the damage. Similarly, there are rules for the player. So we'll implement those rules through conditionals later. The game starts off with, this being the CPU's, or the computer's turn. We start off with the health for both the wizard and the goblin as 100. The roll button has a value, that the roll button is stored in an X and Y value of 110 and 250, with a width and height of 80 and 40. So let's first, simulate the die value. and see what numbers come out of that, because we want random numbers to come out of the die. To do that, we use the random function. The random function takes in a couple of arguments, one, the starting number and the ending number, and produces numbers between the starting and the ending number, which means it would produce all the values from 1 up to 20.9999 and not 21. So let's, Look at what the outputs of the dival value are. Okay, so again, I should… I'm expecting to see a number between 1 and 21, and I'm finding 12, I'm finding 9, so these numbers are different every time. So, so this is the mechanism I'm going to use in order to inflict damage. But note that these are floating-point numbers, and I would like to use only integer numbers. To only have integer numbers, use the word floor in front of random. what it does is, float would contain… con… convert a 19.3 to a 19. So it converts the values to the nearest lower integer. So if it's 20.99, it would convert it to 20. So now we have only integer values, that are generated from the random number. Alright, let's just park this and work on the other pieces of code, and we'll pick up this logic as we implement the logic for as we implement the logic for, Damage inflictions. Good. Okay. So, the draw function contains, how the characters are set up. As you can see, the, wizard is set up using a combination of ellipses and, some triangles, which is, the goblin is set up, using a combination of, shapes that are characterized by vertex values. So, if you wanted to create a shape, for the… for the ear, similar to the ear, then use the begin shape and end shape by giving these vertices values. The roll button is, Using the X and… note that using the X and Y value of… and the width, and height of the roll button, a rectangle is created, and some text is filled inside the rectangle. So we are going to start building the logic for the turn-taking, as well as the win and lose condition. So let's look at the win and lose condition. The win condition is… for the wizard is if the… well, if the health of the goblin becomes less than or equal to zero. That means, let's do a console log, the clear myths. Let's set the game state to… But… Else? Which means the wizard's value, well, else if the wizards. health. Is less than or equal to 0. Let's set the game state to… Loose. Right? Okay, so now, how do we check this? Let's go all the way to the top, let's set the wizard's health to be 0, and then see, observe that. the game state value is printed. Alright, so that doesn't seem to be printed. Let's do a console log here as well, game state, to say that the goblin wins. Okay, so we have the goblin winds that's displayed, that's because the value of the wizard is being set to zero. Now let's… conversely, set the value of the goblin to 0, we see that the player wins. Okay, so that's the initial condition for the winning or losing, and that seems to work well. Now, let's do a set of, Let's do a set of… conditions to simulate turn-taking. So, we'll first start off with the condition for the CPU. So, if… the game… state equals CPU, which means… so game state is one variable that contains information, four pieces of information. It contains information about whether the game is won or lost, or whose turn it is. player state of CPU. Let's create a couple of other conditions, just so that, for game state equals win. So we have all the game states here, and win equals lost. And I'll tell you in a bit what we're going to do for these two bits. What we'll do here is add a text, that says, player wins, and put it right below the end of the screen. So, width by 2, height minus 30. Similarly, let's do one for… Goblind ones. And then width by toque, height minus 30. So how… how can we test this? I'm going to make one of these values 0. Run the code. Okay, so the goblin's value zeros, the player widths. Okay, great. Perfect, so let's just make these values 100 again. So now we want to implement the logic for the CPU, and the idea is that we're going to follow three rules. First rule is if First, let's generate a random value. So, remember how I did this? I want to create a random value between 1 and 21, right? Now, there are three rules. If this value It's less than 7. then… No damage is inflicted on the… on the… on the player, which means… Wizards Health. does not change. So let's… we don't have to write any code here. Else, if we find that the value is between greater than or equal to 7, And? The value is less than 13, No, this means that… The damage is equal to the dice score, which means wizard's health, equals… Wizard Health, minus the dice score, which is D20. And finally. health, which means the value is going to be between 30 and 20. We are going to double the damage, which means wizard Health equals wizard Health minus 2 types. The value of the die. Bye. Cool, so let's, simulate this, and for each time there is… the wizard's health decreases, let's say wizard's Help is… And concatenate the… Value of the health. Okay, so what's happened is, the goblin has successfully… succe… the… successively knocked off, the health of the wizard, and it turns out that the goblin has won. Alright? Note that there are a couple of times when, we see these two. Okay, let's… okay, let's add a console to say that the goblin is missed in this turn. Okay, let's simulate. So the number starts with… 100… The number starts with 100, the wizard Health then goes to 34, the goblin seems to have missed its turn, And then the goblin again hits the wizard, where the wizard health scores less than 0, which means the goblin wins, and that statement is continuously printed. Right? So, this is the basic structure of inflicting damage. However, we still have some more things to do. We still have to write the logic for turn-taking. So, one thing to do is… In games like this, the rule is that the goblin hits the wizard once, and then passes the turn over to the wizard. Which means… Once the goblin has played its turn, which is one of these things, the game state has to change to the player. So let's change the game state to the player. And now run the code, we find that the goblin has only inflicted 1 damage on the player. Okay, this is perfect. So what we now want to do is implement a logic for the player to inflict damage on the goblet. So for this, the player has to click, somewhere in the roll button, and we have to implement a collision detection to detect that and inflict damage. So let's do that. Let's first do the collision detection. The… The collision detection, here means that if the X and Y value of the mouse is between these particular bounds. And there is a mosque. pressed, which is… which is the interaction, that we are recognizing for, and if the press happens, when a mouse is between, this particular X value and Y value, then we simulate, when we simulate the player start. So let's first do the collision detection for this. If roll button.x is greater than Sorry, if… mouse X is greater than roll buttons X, which is this particular point. And mouse X is less than roll button X plus the width of the roll button. And, similarly for mouseY, is greater than rollButton.y, and mouseY is Press done. Roll button.y plus. Roll button. dumped height. Again, that's here to here, so we're essentially covering the edges of the rectangle, so anything inside is acceptable. Let's do a console log and say clicked. Again, I'm just doing this step-by-step so that So, okay, so I'm clicking everywhere else. And then I'm clicking inside, there is a click. Again, there is a second click, and a third click, and so forth. Okay, so I'm just ensuring, step by step, that every bit of code that I write works, and every bit of code I write is tested, and I build on it very systematically. Cool. So now we are going to again implement the logic for inflicting damage. So let's use the same variable, D20. Floor random. Value between 1 and 21. Now, let's look at the rules for the player. The rules for the player are slightly different. If the player rolls less than 5, there is no damage. More than 15, double the damage. Anything in between, dice score is the damage. So, let's write those conditions. If D20 is less than 5, Then, let's just do a console log saying the player missed. else, if the value of D20 is greater than or equal to 5, note that I'm using a greater than or equal to because I want to include the 5. D20 is less than 15, then now I'm going to take off from the goblin cell equals goblin health minus D20. else, if the value is greater than 15, let's just copy this, and then add 2 times T20, because we want to inflict double the damage. And then at the end, let's do console.log goblins. health is… Goblin Health. Perfect. Okay, let's run this and see. So, initially, the goblin seems to have missed, now it's waiting for the player's turn. Let me click this. Alright, the player also seemed to have missed. Let's roll again. Okay, now the player has begun inflicting damage. But note that the goblin is no longer taking its turn, and the reason is because the game state never changes to the goblin, so I need to add one more line here, which says the game state equals CPU. Right? Now, only because I changed the game state, the goblin's turn gets simulated. So let's start here. The goblin… so now, I think we're nearly close to completing this. The goblin starts off by, missing. Let's roll the die for the player. player has inflicted some damage, the goblin has inflicted damage, again, so which is 9, so 9 points were knocked off. Let's roll again. Now, the player seems to have missed, and the goblin, has inflicted some damage. My… the player score is reduced. Do this again. The player seems to have missed again. Well, no. The player seems to have missed again. The goblins really made a dent. The score came down from 83 to 49, and the reason for that is probably rolled a number greater than 13 and inflicted double the damage. So let's look at what the player does. Now, the player has inflicted damage by rolling a number greater than 15, so double the damage. Now, both of them have inflicted a lot of damage. The player is at 2, the goblin's at 4, we are at the end condition. Cooper inflicts damage in the next round first. Now, it's the goblin's turn. If the goblin inflicts the damage, it wins the game, or else the player wins the game. The goblin missed in the last turn. The player seems to have inflicted some damage on the goblin. The value is less than 9, which means the game state is set to win, because the goblin's health is less than 0. We can create many, many other different, versions of this each time a random number is rolled, which means the outcomes of the game are going to be different. So in this run of the game, the player lost the game and the goblin won the game. Right, so hopefully this refreshes some of the concepts that you've learned about randomness, collision detection, conditionals, as well as storing different turns and game state, and helps you when you build your game character, where there is an interaction between the different elements, such as canyons, collectibles, and so on. Cool. One other concept that I wanted to quickly refresh, and this is something that keeps coming up, is the idea of anchoring. The idea of anchoring is to draw complex objects around a specific point or a set of points that serve as the anchor points. We often do not, we do not… we often do not… consider hard-coding values as an elegant solution, so as much as you can build characters with relative ratios and proportions based on anchor points, that would be more desirable. So I just wanted to show you an example of good anchoring. So we have a simple character on screen, which has, an X position, Y position, a width, height, and a head. So the head has also a height of 50, a radius of 50. Now, I've made two points available for you. That would be the anchor point, anchor points of the two components of the, object. The… note that… I have only one character, X and Y, and that's the anchor point, and that is the center of the screen. Using that particular point, a rectangle is… a red rectangle is drawn, upwards, so let me… Show you, how this is done. Character X is this particular point. This is the entire width, character minus width by 2 is this particular point. Character Y is, again, this particular point on the screen. Character Y minus height is this particular point. So we're drawing a rectangle using this particular point. Starting from there, we're drawing a rectangle with a width of character width and a height of character height. So that's this particular rectangle, right? Now, using the same anchor point. I'm now drawing a green ellipse. The difference between these two anchor points is that they have the… they have the same X value, but the Y value is This distance, which is the height, minus this distance, which is the radius of the head by 2. Which means my starting values are character X, character Y minus, character head minus character height, which is this particular point. From then on, you would draw an ellipse, which is of radius, character head, and character head. The reason, you can… well, the usefulness of building objects like this with relative anchoring is that you can now change each of the characters, such as character X, and centered around the same anchor point, all the… all the components of a complex object would move. So let's do, similarly, character Y plus plus. I see the object moving as one coherent entity, as opposed to having different hard-coded values, and then finding out how those specific values can move the object together on the screen as a coherent entity. So, I just wanted to point your attention, go back to the videos on anchoring, ensure that you build a character with coherent anchor points with anchoring sensible, and not too wide, or anchoring outside the particular object. Okay, so let's look at the main components of the submission for the upcoming project. --- KEY SUBMISSION REQUIREMENTS =========================== You are required to, you're required to submit 3 specific components. 1. ZIPPED PROJECT (80% of grade) - sketch.js file - index.html file - p5 library (p5.min.js) - All zipped in one folder 2. PDF DOCUMENT - Take sketch.js, convert to PDF - Label which parts are original code vs adapted from lecture material - If all code is your own, make a statement at the top 3. EXCEPTIONAL WORK DESCRIPTION (discretionary grading) - 100-word description of what you did beyond basic requirements - Only eligible if you score 80%+ on basic requirements - Looking for: technical complexity, elegant code, finished quality - Examples: more game states, interesting procedures, connecting scenery to character movement --- So let's quickly look at Coursera to see how the game page, the submission page looks like. the three different components are mapped on… mapped to the submission points like this. This is where you upload the project. This is where you would upload the text format of your code as a PDF file with clear indications on which parts were originally written by you. And here is about a 100-word description on what you have done that goes beyond the original material, that has been taught. Let's look at the main instructions for the submission. You can review them as text instructions or download them as a PDF file. In terms of how do you go about this, make a copy of the code from the 3B, and then expand on that. What… The first couple of instructions tell you how to draw tree positions, different multiple trees. Note that trees would be drawn using a for loop, and the for loop needs to use the dynamic iterator, which is the length attribute in order to loop every single element. Pay particular attention to how to define the data structures that are required to define multiple trees. In this case, trees is described as an array of numbers. If you specify trees as any other data structure, then a mark would be detected for that. Once you finish the trees, move on to draw clouds, like before. Look at the type of data structure for clouds, and then draw them using a for loop. Similarly, for mountains. The, one of the more detailed, sort of, involved parts of this is to implement scrolling. For this, I would suggest you to look at the instructions and try to follow them as carefully as possible. The main thing to be aware of, and we've seen some students make mistakes in this, is you have to keep the character at the center of the screen. So the character is sort of the titular element, and as the character moves, the scrolling moves in order to keep the character at the center of the screen. Right? So I would suggest having a look through some of these in much more So look through the instructions for scrolling carefully, and ensure that you have a working version on that. --- PROGRAMMING REQUIREMENTS ======================== - Proper indentation (consistent style throughout) - Remove unnecessary whitespace - Remove/comment out console.log statements used for debugging - Declare all variables used in code - Remove redundant/unused variables - Clear distinction between global and local variables - Brief comments (enough to understand code after 4 months, but not too verbose) --- In addition to the functional aspects of the game, we will also look for programming things, such as whether you've used correct indentation. There are two types for indentation. For instance, if you use an if statement, you can use, Sorry. In terms of indentation, always ensure that things inside flower brackets, for instance, after an if statement or after a for loop, are appropriately indicted. If there are any unnecessary white spaces, remove them. If there are any console statements that you've used to debug code. comment them, which are, like, unused commented code, remove them. I understand that we would often have to write these console statements to ensure that our code works correctly, but it's good to remove, but it's necessary to remove them when you submit it for evaluation. Always ensure that you declare variables that are used in the code if there are any redundant or unused variables. remove them. Make a clear distinction about the global and the local variables. Global variables are all at the beginning of the code. Local variables, such as variables inside functions, or variables inside for loops are dynamically declared. Whenever you, include very brief comments, the general rule of thumb for commenting is that, think of it as you are returning to this code after 4 months. you should have enough information there to understand what you were doing at that particular point in time, 4 months back. So that's the gold standard for writing descriptive commits. too many comments, then that makes it too verbose and difficult for us to evaluate the code. So, too few means that you've not commented the code enough. So, think of this rule of thumb to add comments to your code. Okay, I've already covered the submission formats in the original sections, as well as the exceptional work. Look at the criteria for this Look at the distribution of points for each of the aspects, and… The rubric for this tends to be really procedural, so if we have said certain things about how program and code should be, ensure that you adhere to all the things that we have said in order to get the maximum grades. Okay. As a part of your exceptional work, you are required to write 100 words of description, you could get feedback on those 100 words using Studiosity, which is a feedback system on academic writing that's available to you. The feedback would be focused on writing style and academic practice, and this would not be, And you would not get any advice on code, as they are not CSMAT or subject experts. This is a university-level service, however, if you would like to get information on, feedback on your write-up, you can use Studiosity, and I suggest you to make use of this good service there. So, that's mainly the content for this webinar. You would have one more webinar, likely in Feb or March, Feb, I think, and that would be focused on more techniques for the interim webinar. --- FREQUENTLY ASKED QUESTIONS ========================== Q: Is there a theory exam? A: No, grading is only based on the project. Sleuth progress doesn't count but helps understand concepts. Q: What is the midterm assignment? A: The game project up to and including Part 4. Take Part 3B, duplicate it, and work on Part 4. Q: Is there a time limit? A: No time limit like an exam, but there's a deadline (January 7th, 1:59 UK time). Q: Should I submit multiple versions? A: Work up to a satisfactory, error-free version and submit. If experimenting further, freeze stable version first. Q: Can I draw other objects (bagel, cactus, etc.)? A: Yes, but don't break anything in the code. Code must be working and functional. Q: Can I use functions? A: Not recommended - we teach functions in weeks 10-20 and using them now may conflict with later teaching and cause errors. Q: Can I use external libraries? A: No, build the game by writing your own code. Q: Is following lecture code plagiarism? A: No, but best practice is to write your own code. Human checkers review patterns beyond Turnitin scores. Q: Is there a limit on game object complexity? A: Not really, but 15-20 lines is good for a complex object. Larger code becomes difficult to manage. Q: What counts as exceptional work? A: Technically complex things, enhanced game logic, interesting game states, concise logic, clarity in implementation, overall finished quality. It's usually a combination of things. Q: Can I use different indentation styles? A: Yes, either style (brackets on same line or next line) is fine, but be consistent throughout. Q: Can I add music? A: Save for the next submission. Focus on getting basic version working first. Q: Will marks be deducted for using techniques from later course materials? A: No additional points, but risk of errors that would lose points. Stick to content from weeks 1-10. Q: Can I add cutscenes? A: Yes, if using native P5 code and it doesn't break anything. Don't use external libraries. Q: Will I lose points for using functions? A: No, but not suggested as it may conflict with later teaching. Q: What about peer-to-peer assessments? A: They are formative (don't count toward grade) but mandatory to complete to pass the course. Q: Can I include URLs in comments for complex ideas? A: Yes, especially for P5.js documentation exploration. Q: Do I need to stick to mountain/tree scenery? A: No, equivalent complexity objects are fine. Use same programmatic concepts (loops, shapes, etc.). Q: Do I need comments on every line? A: No, balance is key. Comment bespoke/non-obvious logic, not obvious things. Q: Will too many comments deduct marks? A: Yes. --- KEY TAKEAWAYS ============= 1. Deadline: January 7th, 1:59 UK time 2. Submit: zipped project + PDF with labeled code + 100-word exceptional work description 3. Data structures matter: trees = array of numbers, clouds/mountains = arrays of objects 4. Keep character at center of screen for scrolling 5. Use relative anchoring for game objects (not hard-coded values) 6. Remove debug console.log statements before submission 7. Stick to concepts taught in weeks 1-10 only 8. Don't use external libraries or functions 9. Test code step-by-step as you build 10. Freeze stable versions before experimenting with new features