Display a flashing image

edited April 2016 in Python Mode

Hey there. I, like several other's I've seen in my search, am attempting to program the game of Battleship in Processing 3. It's been quite a trip so far, and I think I may have actually learned more doing this than I am from my Computer Science class. Anyway, at the the start of the game, I would like the user to begin with a blank screen, in which, after a preset amount of time (only two seconds or so), an image flashes in the center, perhaps three or four times, before it stays and text appears at the bottom of the screen. Here's what I have:

def intro():
    global dharma
    global starttime
    fill(colors['black'])
    stroke(colors['black'])
    image(dharma, y+y*.25,y*.25, y*.5,y*.5)

battleship_start I would just call the image, do time.sleep() then call a black rectangle to cover the image and do time.sleep() again, and repeat that however many times I want the image flashed, save that: 1. That probably breaks like all programming effenciency laws, and, 2. The fact that draw() is called ever millisecond or somesuch causes one sleep() to make the entire project to run in second intervals.

Thanks for any help! As an afternote, I will almost definitely be back with more questions on this project. Should those questions go under this topic or be asked as a separate question? Thanks!

Tagged:

Answers

  • I'm afraid I have near to no clue what state is. Looking at your template leads me to believe that even my guess that it is the 'state' of the program is incorrect. That and the fact that Java and I are not exactly besties. If you had to explain it to a small child, what would you say?

  • edited April 2016
    • State is just a made up nick for a technique which stores in some variable a value which represents which task needs to be done at that moment.
    • Function draw() by default is called back about 60 FPS.
    • In order for that "flash" animation to be perceptible, it needs to stay around for some frames.
    • Hence the sketch needs to enter into FLASH state so the necessary code for that animation is executed during a determined # of frames.
    • That's why you're better off looking up for older sketches where the technique was used.
    • Unfortunately they're all in Java Mode. Python Mode is rare around here, sorry.
    • But I know a little Python. I might help ya out in some situations I hope. :-\"
  • It's beginning to make sense, I think! In your template, at the beginning where you have the

    static final int ORIGINAL = 0, CONTRAST = 1, NEGATIVE = 2, WIPE = 3;
    

    is that Java's way of creating the variables the same as saying

    ORIGINAL = 0
    CONTRAST = 1
    NEGATIVE = 2
    WIPE = 3
    

    in Python? In the template, the keyPressed() function is only connected to draw() in that it alters the variables that draw() is checking to determine if it is looping or not, correct? I think I'm getting it, man!

  • edited April 2016

    is that Java's way of creating the variables the same as saying

    They're rather more constants than variables in Java due to final.
    Python doesn't have that specific feature. But it's not that important. :-j

    Although I'd convert static final int ORIGINAL = 0, CONTRAST = 1, NEGATIVE = 2, WIPE = 3;
    As this more compact statement in Python: ORIGINAL, CONTRAST, NEGATIVE, WIPE = range(4)

    Just be aware that you're sketch's requirements are more complex than that example.
    It's a game and can't use noLoop(). It's always displaying some animation.
    The states determine what needs to be displayed/done for each draw() frame. :-B

  • ORIGINAL, CONTRAST, NEGATIVE, WIPE = range(4)

    Like I said about learning more from this than from my class. I didn't even know that was possible!

    I think that I have states under control, at least as much of a grasp as I need for this project. But now I'm trying to think about the best method of obtaining the flash. I can't imagine that it would be morally appropriate, as a coder, to just overlap several of the images and black rectangles. Would there be a way to remove the image after it is drawn?

  • edited April 2016

    Would there be a way to remove the image after it is drawn?

    Aren't relying on background() as the 1st statement at the top of draw() in order to clear the whole canvas for the next drawings? :-\"

    Best way of removing any drawing is simply by not drawing it anymore! ;;)
    You pick the drawings to do based on current value of variable state. That's the trick. :-$

  • So I need two separate states for the startup, one with the image showing and one without, and just alternate between those two states as many times as I want the image flashed? That seems even more arduous than covering the image with the black rectangle.

  • Seems like you haven't still figured out the idea of program states.
    That's why I've asked ya to look up other examples. (:|

    • Let's say your game has entered state = FLASH.
    • Inside draw() you check which is current state.
    • If it's FLASH, invoke the function which deals w/ that.
    • Of course you've gotta establish the duration of the whole current state.
    • Be it based on # of frameCount or millis() passed.
    • Once finished, the FLASH function needs to update state to ORIGINAL for example.
    • That's the basic idea. I'm not so good at it myself, sorry.
    • Old chap answerer @Chrisir knows how to explain it better. B-)
  • No, that's it. I understand the list as a whole, my issue lies within bullet 3: I've pieced together how to get there, but how do I deal with the flash itself?

  • That's SFX. Not my forté at all. I can't help ya w/ that, sorry! X_X

  • edited May 2016

    i could do it in processing but not in py

    but the principle is as gotoloop said use states to determine in which state you are (pre-flash, flash(on), flash(off), after-flash) and act accordingly

    int state =0;
    

    you can even give the states names:

    final int statePreFlash =0; //  must be unique 
    final int stateFlashOn =1; // 
    final int stateFlashOff =2; //     
    

    all different values of course

    etc.

    now in draw() say

    switch(state) { 
        case statePreFlash: 
        //...
        break; 
    

    etc.

    now the flash itself:

    since you clear (using background or so) the screen at he beginning of draw() only that is visible that you actually draw!!!

    so when state is flashOn show the thing, if it is flashOff don't show it (no black rectangle needed)

    anyway, use a timer to toggle between state=flashOn and state=flashOff

    if(startTime + durationTime < millis()) { 
    
        startTime=millis();
    
        if (state==flashOn) 
               state = flashOff; 
               else state=flashOn;
    
        count++;
    
    }
    
    if(count>=3) 
        state=afterFlash;
    
  • Okay, so rather than have one state with the flashing functionality within, have the flashing functionality comprised of two states. Gotcha. Now, with just the intro gimmick taking two states, is there a limit to how many states I can or should be using?

  • edited May 2016

    rather than have one state with the flashing functionality within, have the flashing functionality comprised of two states.

    that's what I said. Alternatively you could have the states pre-flash, flash, and after-flash only and make an extra boolean var boolean flashOn=false;

    is there a limit to how many states I can or should be using?

    No.

    typical more states would be stateEnterUserName1 and stateEnterUserName1 or stateShowHighScore or stateHelp

    here is a typical program with states:

        //
        // states
        final int stateGame  = 0;  // consts
        final int statePause = 1;
        int state = statePause;    // current state
    
        // ---------------------------------------------------------------
    
        void setup()
        {
          // init (runs only once)
          size(800, 600);
        } // func 
    
        void draw() 
        { 
          // draw() runs on and on 
    
          switch (state) {
    
          case stateGame: 
            // Game
            handleStateGame();
            break; 
    
          case statePause:
            // Pause
            handleStatePause(); 
            break;
    
          default:
            // error
            println("Error number 939; unknown state : " 
              + state 
              + ".");
            exit();
            break;
          } // switch
          //
        } // func 
    
        // ------------------------------------------------------------
    
        // functions for states - called from draw() 
    
        void handleStateGame() {
          // Game
          background(11);
          fill(244, 3, 3); // red 
          text ("Game....", 210, 313);
          signHome(10, 100);
        } // func 
    
        void handleStatePause() {
          // Pause
          background(255);
          fill(244, 3, 3); // red 
          text ("Pause.... ", 210, 313);
          text ("Hit p to start ", 210, 385);
          signHome(width-70, 100);
        } // func 
    
        // ----------------------------------------
        // keyboard input 
    
        void keyPressed() {
    
          switch (state) {
    
          case stateGame: 
            // Game
            keyPressedForStateGame();
            break; 
    
          case statePause:
            // Pause
            keyPressedForStatePause(); 
            break;
    
          default:
            // error
            println("Error number 1039; unknown state : "
              + state 
              + ".");
            exit();
            break;
          } // switch
        } // func 
    
        // ----
    
        void keyPressedForStateGame() { 
          if (key == CODED) 
          {
            if (keyCode == UP) {
              //
            } else if (keyCode == DOWN) {
              //
            }
    
            if (keyCode == LEFT) {
              //
            } else if (keyCode == RIGHT) {
              //
            } else {
              // do nothing
            } // else
          } //  if (key == CODED) {
          else 
          {
            // not CODED ---------------------- 
            if (key == 'p') {
              // Pause 
              state = statePause;
            } else {
              // do nothing
            } // else
          } // else not CODED
        } // func
    
        void keyPressedForStatePause() { 
          if (key == CODED) 
          {
            if (keyCode == UP) {
              //
            } else if (keyCode == DOWN) {
              // none
            }
    
            if (keyCode == LEFT) {
              //
            } else if (keyCode == RIGHT) {
              //
            } else {
              // do nothing
            } // else
          } //  if (key == CODED) {
          else 
          {
            // not CODED ---------------------- 
            if (key == 'p') {
              //
              state = stateGame;
            } else {
              // do nothing
            } // else
          } // else not CODED
        } // func
    
        // -------------------------------------------------------
        // Mouse input
    
        void mousePressed() {
          //
          switch (state) {
    
          case stateGame: 
            // Game
            mousePressedForStateGame();
            break; 
    
          case statePause:
            // Pause
            mousePressedForStatePause(); 
            break;
    
          default:
            // error
            println("Error number 1139; unknown state : " + state+".");
            exit();
            break;
          } // switch
        } // func 
    
        void mousePressedForStateGame() {
          if (dist(mouseX, mouseY, 10, 100) < 30 ) { 
            println ("Hit Game.");
          }
        } // func 
    
        void mousePressedForStatePause() {
          if (dist(mouseX, mouseY, width-70, 100) < 30 ) { 
            println ("Hit Pause.");
          }
        } // func 
    
        // -------------------------------------------------------
        // Misc
    
        void signHome(int x, int y) {
          // gives a sign for a house / home sign
    
          final int width1=6;
          final int height1=8;
    
          fill( 2, 255, 0 );
          strokeWeight(1);
          stroke ( 2, 255, 0 );
          noFill();
          x+=21;
          y+=14;
          triangle ( x-width1, y, 
            x, y-height1, 
            x+width1, y );
          rect(x-width1/2, y, width1, width1);
          rect(x-width1/4+1, y+height1/4+1, width1/4, width1/3);
          strokeWeight(1);
        }
    
        // =================================================================
    
  • Thank you both so much for the help that you've granted so far. Here is my new problem: Python doesn't have a switch statement. And that wouldn't be a problem, save that Python is that language that we've been learning for four months now. I have however found what looks like a switch class that someone created to do the same purpose. Does this look like it will work the same as Switch in Java:

    # This class provides the functionality we want. You only need to look at
    # this if you want to know how this works. It only needs to be defined
    # once, no need to muck around with its internals.
    class switch(object):
        def __init__(self, value):
            self.value = value
            self.fall = False
    
        def __iter__(self):
            """Return the match method once, then stop"""
            yield self.match
            raise StopIteration
    
        def match(self, *args):
            """Indicate whether or not to enter a case suite"""
            if self.fall or not args:
                return True
            elif self.value in args: # changed for v1.5, see below
                self.fall = True
                return True
            else:
                return False
    
    
    # The following example is pretty much the exact use-case of a dictionary,
    # but is included for its simplicity. Note that you can include statements
    # in each suite.
    v = 'ten'
    for case in switch(v):
        if case('one'):
            print 1
            break
        if case('two'):
            print 2
            break
        if case('ten'):
            print 10
            break
        if case('eleven'):
            print 11
            break
        if case(): # default, could also just omit condition or 'if True'
            print "something else!"
            # No need to break here, it'll stop anyway
    
    # break is used here to look as much like the real thing as possible, but
    # elif is generally just as good and more concise.
    
    # Empty suites are considered syntax errors, so intentional fall-throughs
    # should contain 'pass'
    c = 'z'
    for case in switch(c):
        if case('a'): pass # only necessary if the rest of the suite is empty
        if case('b'): pass
        # ...
        if case('y'): pass
        if case('z'):
            print "c is lowercase!"
            break
        if case('A'): pass
        # ...
        if case('Z'):
            print "c is uppercase!"
            break
        if case(): # default
            print "I dunno what c was!"
    
    # As suggested by Pierre Quentel, you can even expand upon the
    # functionality of the classic 'case' statement by matching multiple
    # cases in a single shot. This greatly benefits operations such as the
    # uppercase/lowercase example above:
    import string
    c = 'A'
    for case in switch(c):
        if case(*string.lowercase): # note the * for unpacking as arguments
            print "c is lowercase!"
            break
        if case(*string.uppercase):
            print "c is uppercase!"
            break
        if case('!', '?', '.'): # normal argument passing style also applies
            print "c is a sentence terminator!"
            break
        if case(): # default
            print "I dunno what c was!"
    
    # Since Pierre's suggestion is backward-compatible with the original recipe,
    # I have made the necessary modification to allow for the above usage.
    

    Code by Brian Beck http://code.activestate.com/recipes/410692/

  • edited April 2016

    Very cool solution there! But C/ JS / Java's switch () / case: / default: block is merely some regular Python's if: / elif: / else: block using the equality == operator only! ;))

    https://Processing.org/reference/switch.html
    http://py.Processing.org/reference/else.html

  • Answer ✓

    As an illustration, here's a Java Mode sketch which uses switch () / case: in both draw() & mousePressed(): *-:)
    https://forum.Processing.org/two/discussion/14071/converting-java-code-to-python-for-dataviz#Item_11

    When converted to Python Mode, they've become if: / elif: / else: instead: :ar!
    https://forum.Processing.org/two/discussion/14071/converting-java-code-to-python-for-dataviz#Item_13

  • Wow! That converted code cleared up a whole lot of issues! Thanks! But, of course, here's a new one: When I was first trying to load the font that I was using for the grid, I kept having trouble because Processing said that there was a syntax error right before the PFont, which I was only using because that's what I had seen in all the sketches with text. However when I left PFont out, it worked fine. Until I wanted to use a second font. So am I using text completely wrong? How do I load another font?

  • edited May 2016

    I don't have much experience w/ PFont either.
    But as you already know, look up Processing's reference 1st:

    1. http://py.Processing.org/reference/createFont.html
    2. http://py.Processing.org/reference/loadFont.html
  • I am ashamed: I had the file name mispelled

Sign In or Register to comment.