Function created with Python needs check

For questions about using Classic.

Post » Sat Oct 08, 2011 5:14 am

I had some problems with spawning objects in the edges of the layer (at random positions). I thought of making an array table that is given an appropriate random variable to allow the object to spawn in the correct position.

I drew up a flow chart but was way to convoluted for my taste so I just learned some python for about 10 minutes and wrote this instead to server my purpose.

[code]
def edgeplacement(o,l):
     i = random.randint(1,4)
     xx = 0
     yy = 0
     switch i:
          case i==1:
               xx = 0
               yy = random.randint(0,768)
          case i==2:
               xx = 1024
               yy = random.randint(0,768)
          case i==3:
               xx = random.randint(0,1024)
               yy = 0
          case i==4:
               xx = random.randint(0,1024)
               yy = 768
     else:
          xx = 0
          xy = 0
     newobject = System.Create(o,l,xx,yy)
     newobject.angle = random.random(360)
     return true
[/code]

All it does is take in the type of object to spawn and the layout it spawns. There are only 4 possible sides the object can spawn in, since the whole point is to spawn the object from the sides. Each 'case' represents a side. The parameter 'o' is the object. The parameter 'l' is the layer.

I'm doing this without actually testing it because I'm at a public computer and it doesn't have dx9... well it says it doesn't when I run the exe but I'm pretty sure its just the computer blocking my access.

So, is there anything wrong with it? Is there a much much much simpler way? I'm a complete novice here at python scripting so please tell me if I got something wrong. I need to learn from others not just from books.
B
3
G
1
Posts: 44
Reputation: 563

Post » Sat Oct 08, 2011 9:29 am

* To use random you need to import it prior to using it. It is the best way to import at the beginning of the script:

[code]
import random

def edgeplacement
...
[/code]

* No need for the else-part. You're switching between one of the numbers, that will be generated with randint(1, 4). 'i' will never be set to any other number than 1, 2, 3 or 4.

* No need to explicitly 'return true'. You may safely delete that line.

* As far as I know (but I might be wrong), random.random() isn't used as you would like to. It is used without a number in brackets and returns the next random number everytime it is called, which is a number between 0.0 and 1.0
If I'm right, you better use randint(0, 360) here, or, if you explicitly want decimals, random() * 360

* You don't reference an object by creating it. You need to access it using SOL (selected objects list). I can't work with CC at the moment, but I think it is something like
System.Create(o, l, xx, yy)
newobject = SOL.o
newobject.angle = random.random() * 360

If SOL doesn't accept a reference, then you need to create the object by name.

Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Tue Oct 11, 2011 4:38 am

There's no switch statement in python, and "Create" works with a the text name of the object.

This works:
[code]from random import randint,random

def edgeplacement(o,l):
   # get the name of the object
   objectName= o.__class__.__name__

   if randint(0,1) == 1:
      x = randint(0,1) * 640
      y = random() * 480
   else:
      x = random() * 640
      y = randint(0,1) * 480
   System.Create(objectName,l,x,y)
   getattr(SOL, objectName).angle = random()*360[/code]
B
79
S
24
G
54
Posts: 4,735
Reputation: 40,733

Post » Tue Oct 11, 2011 9:39 am

[QUOTE=R0J0hound] There's no switch statement in python[/QUOTE]



[QUOTE=R0J0hound] and "Create" works with a the text name of the object.[/QUOTE]
That's what I was looking for.


[QUOTE=R0J0hound][code]from random import randint,random

def edgeplacement(o,l):
   # get the name of the object
   objectName= o.__class__.__name__

   if randint(0,1) == 1:
      x = randint(0,1) * 640
      y = random() * 480
   else:
      x = random() * 640
      y = randint(0,1) * 480
   System.Create(objectName,l,x,y)
   getattr(SOL, objectName).angle = random()*360[/code][/QUOTE]
Clean and efficient as always! And again something new to learn. Accessing with __class__ is new as is 'getattr' to me. Thank you for sharing it
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Sun Oct 16, 2011 5:18 am

Thanks heaps R0J0hound. Just knowing how to retrieve names and attributes helped a lot. If only there was some more in depth tutorial of the integration of python and CC or at least a descriptive reference table. I might make one once I master the basics.

I'll digress. I have been wondering how I could make a sprite object appear near this object called 'player'. I wanted to make a proper range limit to it, as in randomly spawn in a circular area around 'player'.

So here's what I've come up with. Using some basic Pythagoras Theorem to randomly spawn objects in a circular area relative to 'player'.

[code]from random import random,randomint,choice
from math import sqrt,pow

def SpawnNearPlayer(o,l,rangeMin,rangeMax):
     objectN = o.__class__.__name__
     playerN = player.__class__.__name__
     
     rads = randomint(rangeMin,rangeMax)     #distance from 'player' object
     xside = randomint(1,rads)*randomint(-1,1)     #randomising x-axis
     yside = sqrt(pow(rads,2) - pow(xside,2))*choice(-1,1)     #randomising y-axis to fit x-axis and distance
     
     #create the object relative to 'player'
     System.Create(objectN,l,
          int(xside)+getattr(SOL,playerN).x,
          int(yside)+getattr(SOL,playerN).y)[/code]

I know there must be a more clean or better way of doing this but with only couple of weeks total experience in programming I'm still a newb.

Also there is another problem. The function I just wrote will definitely create objects out side the screen too (outside the game boundaries). This may cause some issues and I was wondering is there a way to cut out the area that is outside the screen?

I mean to say is there some kind of method that takes into consideration the boundaries of the game so my function won't choose a vector there?

I must learn more but the official python manual is a pain to read through. All I need to know is things that are slightly advanced than beginner's (since I attempted to learn C#).
B
3
G
1
Posts: 44
Reputation: 563

Post » Sun Oct 16, 2011 8:55 pm

Here's good python reference that I use all the time that is easier use than the official docs.
http://www.tutorialspoint.com/python/

Here's my working of the problem.
[code]from random import random,randint
from math import sin,cos

def SpawnNearPlayer(objectName, layer, rangeMin, rangeMax):
   # calculate random polar coordinate.
   random_angle = random()*360
   random_distance = randint(rangeMin,rangeMax)
   
   # calulate x,y from angle and distance from Player.
   x = random_distance * cos(random_angle) + Player.X
   y = random_distance * sin(random_angle) + Player.Y
   
   #check to see if x,y will be on the layout
   if 0 <= x <= System.LayoutWidth and 0 <= y <= System.LayoutHeight:
      #Yes. create the object
      System.Create(objectName, layer, x, y)
   else:
      #No. Try a different point.
      SpawnNearPlayer(objectName, layer, rangeMin, rangeMax)[/code]

I eliminated the __class__.__name__ bit as it looks too cluttered. You now pass the object's name to begin with instead of the object type.
So instead of calling the function like this:
[code]SpawnNearPlayer(Sprite,1, 50,100)[/code]
Do this (notice the quotes):
[code]SpawnNearPlayer('Sprite',1, 50,100)[/code]
B
79
S
24
G
54
Posts: 4,735
Reputation: 40,733

Post » Sun Oct 16, 2011 10:31 pm

Yet again I thank you. You're about the best help I got here. If only there was a 'like' button... lol

And, ah, I see how you get x and y. It's from something in the lines of (x-a)^2+(y-b)^2=r^2 isn't it? Didn't know that 't' in cos or sin * 't' was the angle between the two points relative to the x axis. Thanks again. ^^
B
3
G
1
Posts: 44
Reputation: 563

Post » Mon Oct 17, 2011 4:57 am

Are you using python for any particular reason, or just trying to learn?
QuaziGNRLnose2011-10-17 04:57:29
B
52
S
7
G
6
Posts: 1,945
Reputation: 7,610

Post » Mon Oct 17, 2011 7:17 am

Right now I'm both using python to create various functions for my game and learning at the same time.

But then I did use GML for almost everything in GM8. So in the end I might use more python scripts than I'll click and drag for almost everything.
B
3
G
1
Posts: 44
Reputation: 563

Post » Mon Oct 17, 2011 7:43 am

I wouldn't do so. Construct's event system is very powerful. There are rare occasions where you need to use python or develop your own plug. But almost everything can be done just with events - really :)

(And events will be executed a lot quicker than python scripts)
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Next

Return to Help & Support using Construct Classic

Who is online

Users browsing this forum: No registered users and 3 guests